Pandas 枢轴 table 保持 table 完整
Pandas Pivot table keeping the table intact
假设我们有以下 table
df = pd.DataFrame.from_dict({
'col1': list('abcadeabba'),
'col2': range(10),
'col3': [list('abc'), list('d'), list('e'), list('ba'), list('de'),
list('abc'), list('ae'), list('e'), list('dc'), list('a')]
})
df
我需要 col1
值作为列,新列下的值将基于 col3
,默认值为 0;对应于 col3
值的列应为 1,其他新列值应为行中的 0。此外,col2
应该保持原样。
所以,第一行如下所示
我尝试了 pivot_table
但没有找到使用 col3
填充值的有效方法
根据 col1
的唯一值使用 MultiLabelBinarizer
for good performance solution and then append to original with DataFrame.reindex
,如果不存在则添加列 0
列:
from sklearn.preprocessing import MultiLabelBinarizer
mlb = MultiLabelBinarizer()
df1 = pd.DataFrame(mlb.fit_transform(df['col3']),columns=mlb.classes_)
print (df1)
a b c d e
0 1 1 1 0 0
1 0 0 0 1 0
2 0 0 0 0 1
3 1 1 0 0 0
4 0 0 0 1 1
5 1 1 1 0 0
6 1 0 0 0 1
7 0 0 0 0 1
8 0 0 1 1 0
9 1 0 0 0 0
df = df.join(df1.reindex(df['col1'].unique(), fill_value=0, axis=1))
print (df)
col1 col2 col3 a b c d e
0 a 0 [a, b, c] 1 1 1 0 0
1 b 1 [d] 0 0 0 1 0
2 c 2 [e] 0 0 0 0 1
3 a 3 [b, a] 1 1 0 0 0
4 d 4 [d, e] 0 0 0 1 1
5 e 5 [a, b, c] 1 1 1 0 0
6 a 6 [a, e] 1 0 0 0 1
7 b 7 [e] 0 0 0 0 1
8 b 8 [d, c] 0 0 1 1 0
9 a 9 [a] 1 0 0 0 0
这是另一个解决方案,
import pandas as pd
df = pd.DataFrame.from_dict({
'col1': list('abcadeabba'),
'col2': range(10),
'col3': [list('abc'), list('d'), list('e'), list('ba'), list('de'),
list('abc'), list('ae'), list('e'), list('dc'), list('a')]
})
dummies_ = pd.get_dummies(df['col3'].explode())
print(pd.concat([df, dummies_.groupby(dummies_.index).sum()], axis=1))
col1 col2 col3 a b c d e
0 a 0 [a, b, c] 1 1 1 0 0
1 b 1 [d] 0 0 0 1 0
2 c 2 [e] 0 0 0 0 1
3 a 3 [b, a] 1 1 0 0 0
4 d 4 [d, e] 0 0 0 1 1
5 e 5 [a, b, c] 1 1 1 0 0
6 a 6 [a, e] 1 0 0 0 1
7 b 7 [e] 0 0 0 0 1
8 b 8 [d, c] 0 0 1 1 0
9 a 9 [a] 1 0 0 0 0
假设我们有以下 table
df = pd.DataFrame.from_dict({
'col1': list('abcadeabba'),
'col2': range(10),
'col3': [list('abc'), list('d'), list('e'), list('ba'), list('de'),
list('abc'), list('ae'), list('e'), list('dc'), list('a')]
})
df
我需要 col1
值作为列,新列下的值将基于 col3
,默认值为 0;对应于 col3
值的列应为 1,其他新列值应为行中的 0。此外,col2
应该保持原样。
所以,第一行如下所示
我尝试了 pivot_table
但没有找到使用 col3
根据 col1
的唯一值使用 MultiLabelBinarizer
for good performance solution and then append to original with DataFrame.reindex
,如果不存在则添加列 0
列:
from sklearn.preprocessing import MultiLabelBinarizer
mlb = MultiLabelBinarizer()
df1 = pd.DataFrame(mlb.fit_transform(df['col3']),columns=mlb.classes_)
print (df1)
a b c d e
0 1 1 1 0 0
1 0 0 0 1 0
2 0 0 0 0 1
3 1 1 0 0 0
4 0 0 0 1 1
5 1 1 1 0 0
6 1 0 0 0 1
7 0 0 0 0 1
8 0 0 1 1 0
9 1 0 0 0 0
df = df.join(df1.reindex(df['col1'].unique(), fill_value=0, axis=1))
print (df)
col1 col2 col3 a b c d e
0 a 0 [a, b, c] 1 1 1 0 0
1 b 1 [d] 0 0 0 1 0
2 c 2 [e] 0 0 0 0 1
3 a 3 [b, a] 1 1 0 0 0
4 d 4 [d, e] 0 0 0 1 1
5 e 5 [a, b, c] 1 1 1 0 0
6 a 6 [a, e] 1 0 0 0 1
7 b 7 [e] 0 0 0 0 1
8 b 8 [d, c] 0 0 1 1 0
9 a 9 [a] 1 0 0 0 0
这是另一个解决方案,
import pandas as pd
df = pd.DataFrame.from_dict({
'col1': list('abcadeabba'),
'col2': range(10),
'col3': [list('abc'), list('d'), list('e'), list('ba'), list('de'),
list('abc'), list('ae'), list('e'), list('dc'), list('a')]
})
dummies_ = pd.get_dummies(df['col3'].explode())
print(pd.concat([df, dummies_.groupby(dummies_.index).sum()], axis=1))
col1 col2 col3 a b c d e
0 a 0 [a, b, c] 1 1 1 0 0
1 b 1 [d] 0 0 0 1 0
2 c 2 [e] 0 0 0 0 1
3 a 3 [b, a] 1 1 0 0 0
4 d 4 [d, e] 0 0 0 1 1
5 e 5 [a, b, c] 1 1 1 0 0
6 a 6 [a, e] 1 0 0 0 1
7 b 7 [e] 0 0 0 0 1
8 b 8 [d, c] 0 0 1 1 0
9 a 9 [a] 1 0 0 0 0