使用 pandas 合并具有相同列名的两列
Combine two columns with same column name using pandas
我有一个数据框 (df),其中两列的长度不同。我想将这两列合并为一列。我该怎么做?
table 如下所示:
Col_1
Col_2
Col_1
Col3
A1
12
A1
345
A2
34
A2
980
A3
098
A3
543
A4
8765
A5
765
我想将 Col_1 合并为 table 中的一列。输出应如下所示:
期望输出:
Col_1
Col_2
Col3
A1
12
345
A2
34
980
A3
098
543
A4
8765
A5
765
到目前为止我尝试了什么?
df1 = df.columns[0]
df2 = df.columns[2]
df_merge_col = pd.merge(df1, df2, on='Col_1')
或
df["Col_1"] = df["Col_1"].astype(str) + df["Col_1"]
如果用于按位置过滤的重复列名使用 DataFrame.iloc
, then remove NaNs rows by DataFrame.dropna
和外部连接:
df1 = df.iloc[:, :2].dropna(subset=['Col_1'])
df2 = df.iloc[:, 2:].dropna(subset=['Col_1'])
df_merge_col = pd.merge(df1, df2, on='Col_1', how='outer')
print (df_merge_col)
Col_1 Col_2 Col3
0 A1 12.0 345
1 A2 34.0 980
2 A3 98.0 543
3 A4 NaN 8765
4 A5 NaN 765
这是使用 MultiIndex
和 stack
的通用解决方案。
总而言之,它通过添加唯一 ID 来删除重复列,然后我们将其用于 stack
数据。剩下的只有sorting/cleaning.
(df.set_axis(pd.MultiIndex.from_arrays([df.columns,
df.groupby(level=0, axis=1).cumcount()
]), axis=1)
.stack(level=1)
.sort_index(level=1)
.droplevel(1)
.drop_duplicates(subset=df.columns[df.columns.duplicated()])
)
输出:
Col_1 Col_2 Col_3
0 A1 12.0 345.0
1 A2 34.0 980.0
2 A3 98.0 543.0
3 A4 8765.0 NaN
4 A5 765.0 NaN
您可以通过以下方式使用 np.where
完成此任务:
import numpy as np
import pandas as pd
df = pd.DataFrame([['A1', 'A1'], ['A2', 'A2'], ['A3', None], ['A4', None]])
combined = np.where(df[0].isnull(), df[1], df[0])
df.drop(columns=[0, 1], inplace=True)
df[0] = combined
print(df)
输出
0
0 A1
1 A2
2 A3
3 A4
np.where
就像 pandas.Series
的三元运算符,其中第 0 列没有值 从第 1 列获取值,否则从第 0 列
我有一个数据框 (df),其中两列的长度不同。我想将这两列合并为一列。我该怎么做?
table 如下所示:
Col_1 | Col_2 | Col_1 | Col3 |
---|---|---|---|
A1 | 12 | A1 | 345 |
A2 | 34 | A2 | 980 |
A3 | 098 | A3 | 543 |
A4 | 8765 | ||
A5 | 765 |
我想将 Col_1 合并为 table 中的一列。输出应如下所示:
期望输出:
Col_1 | Col_2 | Col3 |
---|---|---|
A1 | 12 | 345 |
A2 | 34 | 980 |
A3 | 098 | 543 |
A4 | 8765 | |
A5 | 765 |
到目前为止我尝试了什么?
df1 = df.columns[0]
df2 = df.columns[2]
df_merge_col = pd.merge(df1, df2, on='Col_1')
或
df["Col_1"] = df["Col_1"].astype(str) + df["Col_1"]
如果用于按位置过滤的重复列名使用 DataFrame.iloc
, then remove NaNs rows by DataFrame.dropna
和外部连接:
df1 = df.iloc[:, :2].dropna(subset=['Col_1'])
df2 = df.iloc[:, 2:].dropna(subset=['Col_1'])
df_merge_col = pd.merge(df1, df2, on='Col_1', how='outer')
print (df_merge_col)
Col_1 Col_2 Col3
0 A1 12.0 345
1 A2 34.0 980
2 A3 98.0 543
3 A4 NaN 8765
4 A5 NaN 765
这是使用 MultiIndex
和 stack
的通用解决方案。
总而言之,它通过添加唯一 ID 来删除重复列,然后我们将其用于 stack
数据。剩下的只有sorting/cleaning.
(df.set_axis(pd.MultiIndex.from_arrays([df.columns,
df.groupby(level=0, axis=1).cumcount()
]), axis=1)
.stack(level=1)
.sort_index(level=1)
.droplevel(1)
.drop_duplicates(subset=df.columns[df.columns.duplicated()])
)
输出:
Col_1 Col_2 Col_3
0 A1 12.0 345.0
1 A2 34.0 980.0
2 A3 98.0 543.0
3 A4 8765.0 NaN
4 A5 765.0 NaN
您可以通过以下方式使用 np.where
完成此任务:
import numpy as np
import pandas as pd
df = pd.DataFrame([['A1', 'A1'], ['A2', 'A2'], ['A3', None], ['A4', None]])
combined = np.where(df[0].isnull(), df[1], df[0])
df.drop(columns=[0, 1], inplace=True)
df[0] = combined
print(df)
输出
0
0 A1
1 A2
2 A3
3 A4
np.where
就像 pandas.Series
的三元运算符,其中第 0 列没有值 从第 1 列获取值,否则从第 0 列