Python 如何合并/组合熊猫中的列?

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 =

我有一个(示例-)数据框,有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 = ['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()
)。