在 pandas 中使用矢量化计算值并将结果插入数据帧
Counting values and inserting result into dataframe using vectorization in pandas
我有一个包含 35k+ 行的数据表,格式如下:
+----------+---------+--------------+
| username | event | points_value |
+----------+---------+--------------+
| user1 | event_1 | 100 |
| user2 | event_2 | 120 |
| user2 | event_1 | 100 |
| ... | ... | ... |
+----------+---------+--------------+
不确定是否相关,但有 20 种可能的事件,并且每个用户一个事件可能发生不止一次。数据根据事件发生时间排序,而不是根据用户名或事件类型排序。我正在计算每个用户的事件数(以及每个用户和事件添加的点数,但这是一个将通过解决我在下面提出的问题来解决的问题)。
我的输出数据框 events_total_df 使用以下格式:
+----------+---------+---------+-----+----------+
| username | event_1 | event_2 | ... | event_20 |
+----------+---------+---------+-----+----------+
(我已经用用户名预先填充了 events_total_df 数据框,并用 0 填充了每个事件列)
我已经找到了问题的解决方案:
for index, row in df.iterrows():
event_totals_df.loc[event_totals_df.username.eq(row['username']), row['event']] += 1
但是,这是一个非常慢的解决方案。使用当前的 35k+ 行数据表(针对一周的事件),需要几分钟才能完成。我做了一些研究,似乎矢量化是可行的方法,因为它要快得多。但是,我无法让它工作。理想情况下,我喜欢做的是这样的事情:
event_group = df.groupby('event')
for event in list(event_group.groups.keys()):
event_totals_df[event] = len(df.loc[ event_group.get_group(event)['username'] == event_totals_df['username'] ])
但是,当我 运行 代码时,出现以下错误:
ValueError: Can only compare identically-labeled Series objects
这是有道理的。有什么办法可以做我想用矢量化做的事情吗?我愿意改变基本上任何东西来加快速度。但我不认为这是我处理输出数据帧的方式的问题?
尝试 pivot_table:
import pandas as pd
result = pd.pivot_table(df, values=['points_value'], index=['user'], columns=['event'], aggfunc={'points_value':'sum'}).reset_index()
这将汇总每个用户每个事件的所有积分。
我有一个包含 35k+ 行的数据表,格式如下:
+----------+---------+--------------+
| username | event | points_value |
+----------+---------+--------------+
| user1 | event_1 | 100 |
| user2 | event_2 | 120 |
| user2 | event_1 | 100 |
| ... | ... | ... |
+----------+---------+--------------+
不确定是否相关,但有 20 种可能的事件,并且每个用户一个事件可能发生不止一次。数据根据事件发生时间排序,而不是根据用户名或事件类型排序。我正在计算每个用户的事件数(以及每个用户和事件添加的点数,但这是一个将通过解决我在下面提出的问题来解决的问题)。
我的输出数据框 events_total_df 使用以下格式:
+----------+---------+---------+-----+----------+
| username | event_1 | event_2 | ... | event_20 |
+----------+---------+---------+-----+----------+
(我已经用用户名预先填充了 events_total_df 数据框,并用 0 填充了每个事件列)
我已经找到了问题的解决方案:
for index, row in df.iterrows():
event_totals_df.loc[event_totals_df.username.eq(row['username']), row['event']] += 1
但是,这是一个非常慢的解决方案。使用当前的 35k+ 行数据表(针对一周的事件),需要几分钟才能完成。我做了一些研究,似乎矢量化是可行的方法,因为它要快得多。但是,我无法让它工作。理想情况下,我喜欢做的是这样的事情:
event_group = df.groupby('event')
for event in list(event_group.groups.keys()):
event_totals_df[event] = len(df.loc[ event_group.get_group(event)['username'] == event_totals_df['username'] ])
但是,当我 运行 代码时,出现以下错误:
ValueError: Can only compare identically-labeled Series objects
这是有道理的。有什么办法可以做我想用矢量化做的事情吗?我愿意改变基本上任何东西来加快速度。但我不认为这是我处理输出数据帧的方式的问题?
尝试 pivot_table:
import pandas as pd
result = pd.pivot_table(df, values=['points_value'], index=['user'], columns=['event'], aggfunc={'points_value':'sum'}).reset_index()
这将汇总每个用户每个事件的所有积分。