写了 2 天的 Python ,有点奇怪的感觉。。。

62 天前
 woodytang

听说 pandas 很好用,于是决定试一下

目的是这样的: user, amount, datetime A 10 2021-02-12 10:00:00 A 20 2021-03-12 10:00:00 B 30 2021-05-12 10:00:00 B 10 2021-06-12 10:00:00 C 5 2021-05-12 10:00:00 C 10 2021-06-12 10:00:00 C 20 2021-06-12 10:00:00 这是我们常见的数据库的表

最后要做成这样的效果 2021-02 2021-03 2021-05 2021-06 A 10 20 0 0 B 0 0 30 10 C 0 0 5 30


首先我想问一下,这样的需求,大家首先会想到用什么方案(语言,框架,库)做?

column_names = [desc[0] for desc in cursor.description] df = pd.DataFrame(rows, columns=column_names) df['datetime'] = pd.to_datetime(df['datetime']) df['归属年月'] =(df['datetime'].dt.year.astype(str)+ df['datetime'].dt.strftime('%m').astype(str)).astype(int)

到这里把时间字段理好了,变成数字,让它可以排序

grouped_data = df.groupby(['user', '归属年月'])['amount'].sum().reset_index() grouped_data = grouped_data.sort_values('归属年月') 来个二维分组,然后按照‘2021-05’这个来排序一下

df_pivot = pd.pivot_table(grouped_data, index=['user'], columns='归属年月', values='amount', aggfunc='sum').reset_index().fillna(0)

到这里就好了

代码十分简洁,但是这种代码真的有可读性吗?好维护吗?

如果我要算 A 用户所有金额汇总,可以这样写: df_pivot['余额'] = df_pivot.iloc[:, 1:].sum(axis=1)

这个= 让我震惊了,明明执行了函数操作,看上去像是一个赋值操作,这个 python 是怎么实现的?

我编辑器用的 vsc ,python 没有 type hint ,这个有解吗,难道一边写要一边查文档?

还有元组的简写法

a= 1,2,3

看到这个我也是懵了

有没有 pythoner 解答一下,这个语言真的适合写正经项目吗?


js 有 ts 就变得完美了,我很喜欢 python 的生态,有什么可以愉快写 python 的办法?

4205 次点击
所在节点    程序员
33 条回复
dekuofa
61 天前
建议直接上 polars
bianhui
61 天前
静态语言后遗症。多写就好了。世界上流行的语言都有他自己的优势,你要抛开你固有观念,去接纳新鲜事物
nno
61 天前
"这个= 让我震惊了,明明执行了函数操作,看上去像是一个赋值操作,这个 python 是怎么实现的?"
这里其实是 pandas 的 DataFrame 重写了__setitem__接口,当你将对象当做一个 map 来操作的时候,就会触发__getitem__、__setitem__这些内置接口
darkengine
61 天前
光考虑要实现什么功能还不够,还需要考虑:

1 ,这个功能需要长期维护迭代,还是就一次性的数据处理
2 ,团队/个人的能力:包括能不能快速上手某个语言,熟悉某些库,使用某语音,某些库后续好不好招人
suuuch
61 天前
Python 在我的理解里面,是完全为了非科班的人员进入编程的最便捷的路径。

贴近自然语言的语法,脚本直接执行。在学习和自己想快速实现某些小功能的情况下,将环境准备成本将到最低。

比如说,openai 接口刚出来那会,我跟两个朋友弄了个账号一起用。我为了方便,在我买的美帝服务器上做一个转发,及我从国内把 请求服务器上的接口,再从服务器上转发到 openai 的 api 上。。写一下 flask 的固定 token 鉴权,用 supervisor 监控一下。不考虑任何性能。半个小时搞完。。。
SmiteChow
61 天前
还需要多用用,少提见解。
yjhatfdu2
61 天前
这不是一句 sql 查询就能解决的事情吗,为啥要变复杂?
xgdgsc
61 天前
不喜欢这种可以用 julia 无脑 for 循环处理数据
song135711
61 天前
ide 试试 pycharm 社区版。
计算机语言是工具,重要的是使用工具的人。
mkroen
61 天前
@xingfa 感谢分享,已经在做眼保健操了
woodytang
61 天前
@zhzy 大哥,感谢你啊,把我的问题写出来了
woodytang
61 天前
@yjhatfdu2 请赐教,sql 怎么一句写出来~~
yjhatfdu2
57 天前
@woodytang pg 下,如果可以用程序生成返回列然后拼接 SQL ,那么很简单
//创建测试表
create table test3("user" text,amount int,datetime timestamp);
insert into public.test3 (user, amount, datetime)
values ('A', 10, '2021-02-12 10:00:00.000000'),
('A', 20, '2021-03-12 10:00:00.000000'),
('B', 30, '2021-05-12 10:00:00.000000'),
('B', 10, '2021-06-12 10:00:00.000000'),
('C', 10, '2021-06-12 10:00:00.000000'),
('C', 20, '2021-06-12 10:00:00.000000'),
('C', 5, '2021-05-12 10:00:00.000000');
//使用 crosstab 进行 pivot
select *
from crosstab($$select "user",date_trunc('month',datetime)::date::text,sum(amount)
from test3 group by 1,2 order by 1,2 $$,
'select distinct date_trunc(''month'',datetime)::date::text from test3 order by 1') as ct(
"user" text,
"2021-02" text,
"2021-03" text,
"2021-05" text,
"2021-06" text
);
//结果
user | 2021-02 | 2021-03 | 2021-05 | 2021-06
------+---------+---------+---------+---------
A | 10 | 20 | |
B | | | 30 | 10
C | | | 5 | 30

如果要动态生成返回列名,那么确实是相当的麻烦,因为 pg 的查询必须显式制定列,只能用非常别扭的方式
-- 创建一个函数,实际查询的 SQL ,可以反复使用
create or replace function crosstabquery(_t anyelement) returns setof anyelement as
$$
declare
column_list text;
begin
select string_agg(format('%I text', d), ',')
into column_list
from (select distinct date_trunc('month', datetime)::date::text d from test3 order by 1) r;
return query execute ($b$select *
from crosstab($a$select "user",date_trunc('month',datetime)::date::text,sum(amount)
from test3 group by 1,2 order by 1,2 $a$,
'select distinct date_trunc(''month'',datetime)::date::text from test3 order by 1') as ct("user" text,$b$ ||
column_list||')' );
end ;
$$
language plpgsql;
-- 创建返回类型,每次使用前调用
do
$$
declare
column_list text;
begin
select string_agg(format('%I text', d), ',')
into column_list
from (select distinct date_trunc('month', datetime)::date::text d from test3 order by 1) r;
drop type if exists __t;
execute format('create type __t as ("user" text, %s)', column_list);
end
$$ language plpgsql;
-- 返回实际结果
select * from crosstabquery(null::__t);
user | 2021-02-01 | 2021-03-01 | 2021-05-01 | 2021-06-01
------+------------+------------+------------+------------
A | 10 | 20 | |
B | | | 30 | 10
C | | | 5 | 30
(3 rows)

不过如果可以动态生成 sql ,就别用下面这个方案,实在是别扭

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/1027882

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX