Python 将pandas中的列值复制到非零单元格,并在其后聚合列
我有这样的数据框Python 将pandas中的列值复制到非零单元格,并在其后聚合列,python,pandas,dataframe,Python,Pandas,Dataframe,我有这样的数据框 Index P1W1 P1W2 P1W3 P1W4 P2W1 P2W2 P2W3 P2W4 P3W1 P3W2 P3W3 P3W4 0 A B C A D D A 1 B A C C B A 2 C D 我想把它转换成 Index P1 P2
Index P1W1 P1W2 P1W3 P1W4 P2W1 P2W2 P2W3 P2W4 P3W1 P3W2 P3W3 P3W4
0 A B C A D D A
1 B A C C B A
2 C D
我想把它转换成
Index P1 P2 P3
0 A(P1W1) A(P2W2) A(P3W1)
1 A(P1W3) B(P2W4) A(P3W2)
2 B(P1W1) C(P2W2)
3 B(P1W3) C(P2W3)
4 C(P1W3) D(P2W3)
5 C(P1W4) D(P2W4)
6 D(P1W4)
基本上,我想从第一个数据帧中获取包含单元格值的列名,然后在p1p2级别对其进行聚合
如果需要任何澄清,请询问
我完全不知道如何进行此操作,如有任何帮助,将不胜感激设置
txt = """\
Index P1W1 P1W2 P1W3 P1W4 P2W1 P2W2 P2W3 P2W4 P3W1 P3W2 P3W3 P3W4
0 A B C A D D A
1 B A C C B A
2 C D """
df = pd.read_fwf(pd.io.common.StringIO(txt), index_col=0).fillna('')
df
P1W1 P1W2 P1W3 P1W4 P2W1 P2W2 P2W3 P2W4 P3W1 P3W2 P3W3 P3W4
Index
0 A B C A D D A
1 B A C C B A
2 C D
d = df + df.columns.map(lambda c: f'({c})')
pd.concat({
g: d.stack().reset_index(drop=True)
for g, d in d.where(df.astype(bool)).groupby(
lambda col: col[:2], 1
)
}, axis=1).fillna('')
P1 P2 P3
0 A(P1W1) A(P2W2) A(P3W1)
1 B(P1W3) D(P2W3) A(P3W2)
2 C(P1W4) D(P2W4)
3 B(P1W1) C(P2W2)
4 A(P1W3) C(P2W3)
5 C(P1W3) B(P2W4)
6 D(P1W4)
解决方案
txt = """\
Index P1W1 P1W2 P1W3 P1W4 P2W1 P2W2 P2W3 P2W4 P3W1 P3W2 P3W3 P3W4
0 A B C A D D A
1 B A C C B A
2 C D """
df = pd.read_fwf(pd.io.common.StringIO(txt), index_col=0).fillna('')
df
P1W1 P1W2 P1W3 P1W4 P2W1 P2W2 P2W3 P2W4 P3W1 P3W2 P3W3 P3W4
Index
0 A B C A D D A
1 B A C C B A
2 C D
d = df + df.columns.map(lambda c: f'({c})')
pd.concat({
g: d.stack().reset_index(drop=True)
for g, d in d.where(df.astype(bool)).groupby(
lambda col: col[:2], 1
)
}, axis=1).fillna('')
P1 P2 P3
0 A(P1W1) A(P2W2) A(P3W1)
1 B(P1W3) D(P2W3) A(P3W2)
2 C(P1W4) D(P2W4)
3 B(P1W1) C(P2W2)
4 A(P1W3) C(P2W3)
5 C(P1W3) B(P2W4)
6 D(P1W4)
详细信息
txt = """\
Index P1W1 P1W2 P1W3 P1W4 P2W1 P2W2 P2W3 P2W4 P3W1 P3W2 P3W3 P3W4
0 A B C A D D A
1 B A C C B A
2 C D """
df = pd.read_fwf(pd.io.common.StringIO(txt), index_col=0).fillna('')
df
P1W1 P1W2 P1W3 P1W4 P2W1 P2W2 P2W3 P2W4 P3W1 P3W2 P3W3 P3W4
Index
0 A B C A D D A
1 B A C C B A
2 C D
d = df + df.columns.map(lambda c: f'({c})')
pd.concat({
g: d.stack().reset_index(drop=True)
for g, d in d.where(df.astype(bool)).groupby(
lambda col: col[:2], 1
)
}, axis=1).fillna('')
P1 P2 P3
0 A(P1W1) A(P2W2) A(P3W1)
1 B(P1W3) D(P2W3) A(P3W2)
2 C(P1W4) D(P2W4)
3 B(P1W1) C(P2W2)
4 A(P1W3) C(P2W3)
5 C(P1W3) B(P2W4)
6 D(P1W4)
添加用括号括起来的列
df + df.columns.map(lambda c: f'({c})')
P1W1 P1W2 P1W3 P1W4 P2W1 P2W2 P2W3 P2W4 P3W1 P3W2 P3W3 P3W4
Index
0 A(P1W1) (P1W2) B(P1W3) C(P1W4) (P2W1) A(P2W2) D(P2W3) D(P2W4) A(P3W1) (P3W2) (P3W3) (P3W4)
1 B(P1W1) (P1W2) A(P1W3) (P1W4) (P2W1) C(P2W2) C(P2W3) B(P2W4) (P3W1) A(P3W2) (P3W3) (P3W4)
2 (P1W1) (P1W2) C(P1W3) D(P1W4) (P2W1) (P2W2) (P2W3) (P2W4) (P3W1) (P3W2) (P3W3) (P3W4)
使用遮罩在适当的位置制作NaN
。这将使我们能够在理解范围内进行叠加,并为方便起见,删除NaN
d = df + df.columns.map(lambda c: f'({c})')
d.where(df.astype(bool))
P1W1 P1W2 P1W3 P1W4 P2W1 P2W2 P2W3 P2W4 P3W1 P3W2 P3W3 P3W4
Index
0 A(P1W1) NaN B(P1W3) C(P1W4) NaN A(P2W2) D(P2W3) D(P2W4) A(P3W1) NaN NaN NaN
1 B(P1W1) NaN A(P1W3) NaN NaN C(P2W2) C(P2W3) B(P2W4) NaN A(P3W2) NaN NaN
2 NaN NaN C(P1W3) D(P1W4) NaN NaN NaN NaN NaN NaN NaN NaN
通过应用于我们选择的索引对象的
lambda
进行分组。我们将选择axis=1来定位列。这很聪明!问题是,从P10W1开始,所有的都在P1之下。因此,我们有没有办法不把P10和P1I弄错?通过考虑3个字母(P1W)而不是P1,然后将P1W重命名为P1