Python 如何合并/组合熊猫中的列?
我有一个(示例-)数据框,有4列:Python 如何合并/组合熊猫中的列?,python,pandas,dataframe,merge,multiple-columns,Python,Pandas,Dataframe,Merge,Multiple Columns,我有一个(示例-)数据框,有4列: data = {'A': ['a', 'b', 'c', 'd', 'e', 'f'], 'B': [42, 52, np.nan, np.nan, np.nan, np.nan], 'C': [np.nan, np.nan, 31, 2, np.nan, np.nan], 'D': [np.nan, np.nan, np.nan, np.nan, 62, 70]} df = pd.DataFrame(data, columns =
data = {'A': ['a', 'b', 'c', 'd', 'e', 'f'],
'B': [42, 52, np.nan, np.nan, np.nan, np.nan],
'C': [np.nan, np.nan, 31, 2, np.nan, np.nan],
'D': [np.nan, np.nan, np.nan, np.nan, 62, 70]}
df = pd.DataFrame(data, columns = ['A', 'B', 'C', 'D'])
A B C D
0 a 42.0 NaN NaN
1 b 52.0 NaN NaN
2 c NaN 31.0 NaN
3 d NaN 2.0 NaN
4 e NaN NaN 62.0
5 f NaN NaN 70.0
现在,我想将B、C和D列合并到一个新的E列,如本例所示:
data2 = {'A': ['a', 'b', 'c', 'd', 'e', 'f'],
'E': [42, 52, 31, 2, 62, 70]}
df2 = pd.DataFrame(data2, columns = ['A', 'E'])
A E
0 a 42
1 b 52
2 c 31
3 d 2
4 e 62
5 f 70
我发现了一个非常类似的问题,但这在a列末尾添加了合并的列B、C和D:
0 a
1 b
2 c
3 d
4 e
5 f
6 42
7 52
8 31
9 2
10 62
11 70
dtype: object
谢谢您的帮助。用于不带A
的列名,然后获取sum
或max
:
cols = df.columns.difference(['A'])
df['E'] = df[cols].sum(axis=1).astype(int)
# df['E'] = df[cols].max(axis=1).astype(int)
df = df.drop(cols, axis=1)
print (df)
A E
0 a 42
1 b 52
2 c 31
3 d 2
4 e 62
5 f 70
如果每行有多个值:
data = {'A': ['a', 'b', 'c', 'd', 'e', 'f'],
'B': [42, 52, np.nan, np.nan, np.nan, np.nan],
'C': [np.nan, np.nan, 31, 2, np.nan, np.nan],
'D': [10, np.nan, np.nan, np.nan, 62, 70]}
df = pd.DataFrame(data, columns = ['A', 'B', 'C', 'D'])
print (df)
A B C D
0 a 42.0 NaN 10.0
1 b 52.0 NaN NaN
2 c NaN 31.0 NaN
3 d NaN 2.0 NaN
4 e NaN NaN 62.0
5 f NaN NaN 70.0
cols = df.columns.difference(['A'])
df['E'] = df[cols].apply(lambda x: ', '.join(x.dropna().astype(int).astype(str)), 1)
df = df.drop(cols, axis=1)
print (df)
A E
0 a 42, 10
1 b 52
2 c 31
3 d 2
4 e 62
5 f 70
选项1
使用
assign
和drop
In [644]: cols = ['B', 'C', 'D']
In [645]: df.assign(E=df[cols].sum(1)).drop(cols, 1)
Out[645]:
A E
0 a 42.0
1 b 52.0
2 c 31.0
3 d 2.0
4 e 62.0
5 f 70.0
In [648]: df['E'] = df[cols].sum(1)
In [649]: df = df.drop(cols, 1)
In [650]: df
Out[650]:
A E
0 a 42.0
1 b 52.0
2 c 31.0
3 d 2.0
4 e 62.0
5 f 70.0
选项2
使用分配和
删除
In [644]: cols = ['B', 'C', 'D']
In [645]: df.assign(E=df[cols].sum(1)).drop(cols, 1)
Out[645]:
A E
0 a 42.0
1 b 52.0
2 c 31.0
3 d 2.0
4 e 62.0
5 f 70.0
In [648]: df['E'] = df[cols].sum(1)
In [649]: df = df.drop(cols, 1)
In [650]: df
Out[650]:
A E
0 a 42.0
1 b 52.0
2 c 31.0
3 d 2.0
4 e 62.0
5 f 70.0
选项3最近,我喜欢第三个选项。
使用groupby
In [660]: df.groupby(np.where(df.columns == 'A', 'A', 'E'), axis=1).first() #or sum max min
Out[660]:
A E
0 a 42.0
1 b 52.0
2 c 31.0
3 d 2.0
4 e 62.0
5 f 70.0
In [661]: df.columns == 'A'
Out[661]: array([ True, False, False, False], dtype=bool)
In [662]: np.where(df.columns == 'A', 'A', 'E')
Out[662]:
array(['A', 'E', 'E', 'E'],
dtype='|S1')
所写的问题要求合并/合并而不是求和,因此发布此帖子是为了帮助找到此答案的人首先寻求与combine_合并的帮助,这可能有点棘手
df2 = pd.concat([df["A"],
df["B"].combine_first(df["C"]).combine_first(df["D"])],
axis=1)
df2.rename(columns={"B":"E"}, inplace=True)
A E
0 a 42.0
1 b 52.0
2 c 31.0
3 d 2.0
4 e 62.0
5 f 70.0
这有什么难办的?在本例中没有问题,但假设您从不同的数据帧中提取B、C和D值,其中存在a、B、C、D、e、f标签,但不一定是以相同的顺序。combine_first()在索引上对齐,因此需要在每个df引用上加上一组_index()
df2 = pd.concat([df.set_index("A", drop=False)["A"],
df.set_index("A")["B"]\
.combine_first(df.set_index("A")["C"])\
.combine_first(df.set_index("A")["D"]).astype(int)],
axis=1).reset_index(drop=True)
df2.rename(columns={"B":"E"}, inplace=True)
A E
0 a 42
1 b 52
2 c 31
3 d 2
4 e 62
5 f 70
您还可以将ffill
与iloc
一起使用:
df['E'] = df.iloc[:, 1:].ffill(1).iloc[:, -1].astype(int)
df = df.iloc[:, [0, -1]]
print(df)
A E
0 a 42
1 b 52
2 c 31
3 d 2
4 e 62
5 f 70
Zero使用groupby
的第三个选项需要numpy导入,并且只处理要折叠的列集合之外的一列,而jpp使用ffill
的答案要求您知道列的顺序。这是一个解决方案,它没有额外的依赖项,接受任意的输入数据帧,并且只有在列中的所有行都是单值的情况下才折叠列:
将熊猫作为pd导入
数据=[{'A':'A','B':42,'messy':'z'},
{'A':'b','b':52,'messy':'y'},
{'A':'c','c':31},
{'A':'d','C':2,'messy':'w'},
{'A':'e','D':62,'messy':'v'},
{'A':'f','D':70,'messy':['z']}]
df=pd.DataFrame(数据)
cols=['B','C','D']
new_col='E'
如果df[cols].apply(λx:len(x.notna().value_counts())==1,轴=1)。all():
df[new_col]=df[cols].ffill(轴=1).dropna(轴=1)
df2=df.drop(列=列)
打印(df,'\n\n',df2)
输出:
A B凌乱的C D
0 a 42.0 z楠楠楠楠
1 b 52.0 y楠楠楠楠
2 c楠楠31.0楠楠
三维纳米w 2.0纳米
4 e NaN v NaN 62.0
5楼南[z]南70.0
乱七八糟
0AZ42.0
1 b y 52.0
2 c NaN 31.0
3D w 2.0
4 e v 62.0
5F[z]70.0
如果B和C中都有值,会发生什么情况?你打算在E中保留哪一个?好问题-耶斯雷尔的第二个选择进一步说明了这个问题。选项1非常有效。我倾向于选择。1和选择。2,很可能是因为它们的简单性。。。谢谢这个答案适用于字符串,而不仅仅是数字(不同于使用sum()
)。