python - 如何将行与 DataFrame 中的值组合合并
问题描述
我有一个 DataFrame (df1),如下所示
Hair Feathers Legs Type Count
R1 1 NaN 0 1 1
R2 1 0 Nan 1 32
R3 1 0 2 1 4
R4 1 Nan 4 1 27
我想根据每列中值的不同组合来合并行,并且还想为每个合并的行添加计数值。结果数据帧(df2)将如下所示:
Hair Feathers Legs Type Count
R1 1 0 0 1 33
R2 1 0 2 1 36
R3 1 0 4 1 59
合并的执行方式是任何Nan
值都将与 0 或 1 合并。在 df2 中,通过将Nan
Feathers (df1,R1) 的值与 Feathers (df1,R2) 的 0 值合并来计算 R1。同样,Legs (df1,R1) 中的 0 值与 Legs (df1,R2) 值合并Nan
。然后将 R1 (1) 和 R2(32) 的计数相加。以相同的方式合并 R2 和 R3,因为 R2 (df1) 中的 Feathers 值与 R3 (df1) 相似,而 Legs 值Nan
与 R3 (df1) 中的 2 以及 R2 (32) 和 R3 (4) 的计数合并被添加。
我希望解释是有道理的。任何帮助将不胜感激
解决方案
一种可能的方法是复制包含列的每一行NaN
并用列的值填充它们。
首先,我们需要获取每列可能的非空唯一值:
unique_values = df.iloc[:, :-1].apply(
lambda x: x.dropna().unique().tolist(), axis=0).to_dict()
> unique_values
{'Hair': [1.0], 'Feathers': [0.0], 'Legs': [0.0, 2.0, 4.0], 'Type': [1.0]}
然后遍历数据框的每一行,并用每NaN
列的可能值替换每一行。我们可以使用pandas.DataFrame.iterrows
:
mask = df.iloc[:, :-1].isnull().any(axis=1)
# Keep the rows that do not contain `Nan`
# and then added modified rows
list_of_df = [r for i, r in df[~mask].iterrows()]
for row_index, row in df[mask].iterrows():
for c in row[row.isnull()].index:
# For each column of the row, replace
# Nan by possible values for the column
for v in unique_values[c]:
list_of_df.append(row.copy().fillna({c:v}))
df_res = pd.concat(list_of_df, axis=1, ignore_index=True).T
结果是一个数据框,其中所有的NaN
列都填充了可能的值:
> df_res
Hair Feathers Legs Type Count
0 1.0 0.0 2.0 1.0 4.0
1 1.0 0.0 0.0 1.0 1.0
2 1.0 0.0 0.0 1.0 32.0
3 1.0 0.0 2.0 1.0 32.0
4 1.0 0.0 4.0 1.0 32.0
5 1.0 0.0 4.0 1.0 27.0
要Count
通过可能的组合获得分组的最终结果,['Hair', 'Feathers', 'Legs', 'Type']
我们只需要这样做:
> df_res.groupby(['Hair', 'Feathers', 'Legs', 'Type']).sum().reset_index()
Hair Feathers Legs Type Count
0 1.0 0.0 0.0 1.0 33.0
1 1.0 0.0 2.0 1.0 36.0
2 1.0 0.0 4.0 1.0 59.0
希望它服务
更新
如果行中的一个或多个元素缺失,该过程会同时查找缺失值的所有可能组合。让我们添加一个缺少两个元素的新行:
> df
Hair Feathers Legs Type Count
0 1.0 NaN 0.0 1.0 1.0
1 1.0 0.0 NaN 1.0 32.0
2 1.0 0.0 2.0 1.0 4.0
3 1.0 NaN 4.0 1.0 27.0
4 1.0 NaN NaN 1.0 32.0
我们将以类似的方式进行,但替换组合将使用itertools.product获得:
import itertools
unique_values = df.iloc[:, :-1].apply(
lambda x: x.dropna().unique().tolist(), axis=0).to_dict()
mask = df.iloc[:, :-1].isnull().any(axis=1)
list_of_df = [r for i, r in df[~mask].iterrows()]
for row_index, row in df[mask].iterrows():
cols = row[row.isnull()].index.tolist()
for p in itertools.product(*[unique_values[c] for c in cols]):
list_of_df.append(row.copy().fillna({c:v for c, v in zip(cols, p)}))
df_res = pd.concat(list_of_df, axis=1, ignore_index=True).T
> df_res.sort_values(['Hair', 'Feathers', 'Legs', 'Type']).reset_index(drop=True)
Hair Feathers Legs Type Count
1 1.0 0.0 0.0 1.0 1.0
2 1.0 0.0 0.0 1.0 32.0
6 1.0 0.0 0.0 1.0 32.0
0 1.0 0.0 2.0 1.0 4.0
3 1.0 0.0 2.0 1.0 32.0
7 1.0 0.0 2.0 1.0 32.0
4 1.0 0.0 4.0 1.0 32.0
5 1.0 0.0 4.0 1.0 27.0
8 1.0 0.0 4.0 1.0 32.0
> df_res.groupby(['Hair', 'Feathers', 'Legs', 'Type']).sum().reset_index()
Hair Feathers Legs Type Count
0 1.0 0.0 0.0 1.0 65.0
1 1.0 0.0 2.0 1.0 68.0
2 1.0 0.0 4.0 1.0 91.0
推荐阅读
- jquery - 如何向数据表jQuery中的每一行添加类
- python - 从 Python 解释器和 Pycharm 获得不同的结果
- windows - Flutter JSON 序列化 - *.g.dart 文件未生成
- kubernetes-helm - 如何在 Helm 和 ArgoCD 中“重用”随机生成的密码?
- php - 数组结合键php
- go - 是否可以定义一个返回接口的无名函数?
- c# - Visual Studio 打开 Windows 资源管理器
- sql - Google BigQuery 联合查询连接错误
- java - Flyway Mutli Schema:如何在迁移脚本sql文件中指定模式名称
- python - 我在 python Beautiful Soup 中得到一个空列表