如果我有这样的Pandas数据框:
colA colB
A A1
B C1
A B1
B A1
colA具有2个唯一值(A,B),colB具有3个唯一值(A1,B1和C1)。
我想创建一个新的数据框,其中colA和colB都是组合,而另一列colC基于早期df中的组合为1或0。
预期结果:
colA colB colC
A A1 1
A B1 1
A C1 0
B A1 1
B B1 0
B C1 1
答案 0 :(得分:5)
首先使用1
填充的DataFrame.assign
创建新列,然后使用两列的MultiIndex.from_product
值创建Series.unique
,然后在DataFrame.set_index
使用{{3} }-colC
参数可以为fill_value
列中的新附加行设置值:
mux = pd.MultiIndex.from_product([df['colA'].unique(),
df['colB'].unique()], names=['colA','colB'])
df1 = df.assign(colC = 1).set_index(['colA','colB']).reindex(mux, fill_value=0).reset_index()
print (df1)
colA colB colC
0 A A1 1
1 A C1 0
2 A B1 1
3 B A1 1
4 B C1 1
5 B B1 0
替代方法是使用DataFrame.reindex
,DataFrame.set_index
和Series.unstack
来重塑形状:
df1 = (df.assign(colC = 1)
.set_index(['colA','colB'])['colC']
.unstack(fill_value=0)
.stack()
.reset_index(name='ColC'))
print (df1)
colA colB ColC
0 A A1 1
1 A B1 1
2 A C1 0
3 B A1 1
4 B B1 0
5 B C1 1
另一种解决方案是通过DataFrame.stack
创建新的DataFrame
,用indicator=True
创建itertools.product
,重命名列并通过both
进行比较并为{转换为整数从{1}}到True/False
的映射:
1/0
最后必要时按DataFrame.merge
按两列添加排序:
from itertools import product
df1 = pd.DataFrame(product(df['colA'].unique(), df['colB'].unique()), columns=['colA','colB'])
df = df1.merge(df, how='left', indicator=True).rename(columns={'_merge':'colC'})
df['colC'] = df['colC'].eq('both').astype(int)
print (df)
colA colB colC
0 A A1 1
1 A C1 0
2 A B1 1
3 B A1 1
4 B C1 1
5 B B1 0