python - 在 pandas 中插入行,其中一列在 groupby 中缺少某些值
问题描述
这是我的数据框:
user1 user2 cat quantity + other quantities
----------------------------------------------------
Alice Bob 0 ....
Alice Bob 1 ....
Alice Bob 2 ....
Alice Carol 0 ....
Alice Carol 2 ....
我想确保每一user1-user2
对都有对应于每个类别的行(有三个:0、1、2)。如果没有,我想插入一行,并将其他列设置为零。
user1 user2 cat quantity + other quantities
----------------------------------------------------
Alice Bob 0 ....
Alice Bob 1 ....
Alice Bob 2 ....
Alice Carol 0 ....
Alice Carol 1 <SET ALL TO ZERO>
Alice Carol 2 ....
到目前为止,我所拥有的是所有user1-user2
小于 3 个值的列表cat
:
df.groupby(['user1','user2']).agg({'cat':'count'}).reset_index()[['user1','user2']]
我可以遍历这些用户,但这需要很长时间(有超过 1M 这样的对)。我已经检查了基于某些条件在 pandas 中插入行的其他解决方案(例如Pandas/Python 添加基于条件的行和基于条件在Pandas Dataframe 中插入行),但它们并不完全相同。
此外,由于这是一个巨大的数据集,因此必须对解决方案进行矢量化。我应该如何进行?
解决方案
set_index
与reindex
by一起使用MultiIndex.from_product
:
print (df)
user1 user2 cat quantity a
0 Alice Bob 0 2 4
1 Alice Bob 1 3 4
2 Alice Bob 2 4 4
3 Alice Carol 0 6 4
4 Alice Carol 2 3 4
df = df.set_index(['user1','user2', 'cat'])
mux = pd.MultiIndex.from_product(df.index.levels, names=df.index.names)
df = df.reindex(mux, fill_value=0).reset_index()
print (df)
user1 user2 cat quantity a
0 Alice Bob 0 2 4
1 Alice Bob 1 3 4
2 Alice Bob 2 4 4
3 Alice Carol 0 6 4
4 Alice Carol 1 0 0
5 Alice Carol 2 3 4
另一种解决方案是Dataframe
通过列的唯一值和连接的所有组合merge
创建新的right
:
from itertools import product
df1 = pd.DataFrame(list(product(df['user1'].unique(),
df['user2'].unique(),
df['cat'].unique())), columns=['user1','user2', 'cat'])
df = df.merge(df1, how='right').fillna(0)
print (df)
user1 user2 cat quantity a
0 Alice Bob 0 2.0 4.0
1 Alice Bob 1 3.0 4.0
2 Alice Bob 2 4.0 4.0
3 Alice Carol 0 6.0 4.0
4 Alice Carol 2 3.0 4.0
5 Alice Carol 1 0.0 0.0
编辑2:
df['user1'] = df['user1'] + '_' + df['user2']
df = df.set_index(['user1', 'cat']).drop('user2', 1)
mux = pd.MultiIndex.from_product(df.index.levels, names=df.index.names)
df = df.reindex(mux, fill_value=0).reset_index()
df[['user1','user2']] = df['user1'].str.split('_', expand=True)
print (df)
user1 cat quantity a user2
0 Alice 0 2 4 Bob
1 Alice 1 3 4 Bob
2 Alice 2 4 4 Bob
3 Alice 0 6 4 Carol
4 Alice 1 0 0 Carol
5 Alice 2 3 4 Carol
编辑3:
cols = df.columns.difference(['user1','user2'])
df = (df.groupby(['user1','user2'])[cols]
.apply(lambda x: x.set_index('cat').reindex(df['cat'].unique(), fill_value=0))
.reset_index())
print (df)
user1 user2 cat a quantity
0 Alice Bob 0 4 2
1 Alice Bob 1 4 3
2 Alice Bob 2 4 4
3 Alice Carol 0 4 6
4 Alice Carol 1 0 0
5 Alice Carol 2 4 3
推荐阅读
- ios - Firebase 设备细分仅显示“iPhone”
- python - 在多个列上独立使用 TFIDF
- webpack - 如何将 aws_iot_device_sdk_v2 集成到 webpack/react 应用程序中?
- css - Bootstrap 覆盖自己的书面正文
- reactjs - Twilio Flex 网络聊天欢迎消息
- c++ - Rutine 错误 libpqxx:SQL 查询 wrk.exec("") 时出现“字符串太长”
- python - 如何在 Pandas 中将列转换为 DateTime 后更改格式
- python - 如何使用 pandas,每 n 行 agg?
- linux - QEMU 托管启用 MTE 的内核不会引发错误
- javascript - 404错误GET bad request Rapid API React.js,从api url获取sneakerId