📅  最后修改于: 2023-12-03 15:03:32.689000             🧑  作者: Mango
在 Pandas 中,pd.concat() 是非常常用的函数,它可以用于将多个 pandas.DataFrame 或 pandas.Series 进行合并。
然而,当我们在合并两个或多个 DataFrame 或 Series 时,常常会因为存在 NaN 值而出现问题,比如会在合并后的 DataFrame 中得到 NaN 值。
下面是一个简单的示例:
import pandas as pd
import numpy as np
df1 = pd.DataFrame({"A": ["A0", "A1", "A2", "A3"],
"B": ["B0", "B1", "B2", "B3"],
"C": ["C0", "C1", "C2", "C3"],
"D": ["D0", "D1", "D2", "D3"]},
index=[0, 1, 2, 3])
df2 = pd.DataFrame({"A": ["A4", "A5", "A6", "A7"],
"B": ["B4", "B5", "B6", "B7"],
"C": ["C4", "C5", "C6", "C7"],
"D": ["D4", "D5", "D6", "D7"]},
index=[4, 5, 6, 7])
df3 = pd.DataFrame({"A": ["A8", "A9", "A10", "A11"],
"B": ["B8", "B9", "B10", "B11"],
"C": ["C8", "C9", "C10", "C11"],
"D": ["D8", "D9", "D10", "D11"]},
index=[8, 9, 10, 11])
df_concat = pd.concat([df1, df2, df3])
print(df_concat)
输出结果如下:
A B C D
0 A0 B0 C0 D0
1 A1 B1 C1 D1
2 A2 B2 C2 D2
3 A3 B3 C3 D3
4 A4 B4 C4 D4
5 A5 B5 C5 D5
6 A6 B6 C6 D6
7 A7 B7 C7 D7
8 A8 B8 C8 D8
9 A9 B9 C9 D9
10 A10 B10 C10 D10
11 A11 B11 C11 D11
从结果可以看出,我们成功地将三个 DataFrame 按行合并成了一个 DataFrame。但是,当 DataFrame 中存在 NaN 值时,可能会使这个过程变得更为困难。
让我们再创建一个含有 NaN 值的 DataFrame:
df4 = pd.DataFrame({"A": ["A0", np.NaN, "A2", "A3"],
"B": ["B0", np.NaN, "B2", "B3"],
"C": ["C0", np.NaN, "C2", "C3"],
"D": ["D0", np.NaN, "D2", "D3"]},
index=[0, 1, 2, 3])
接下来,我们将它和之前的两个 DataFrame 一起合并:
df_concat = pd.concat([df1, df2, df3, df4])
print(df_concat)
输出结果:
A B C D
0 A0 B0 C0 D0
1 A1 B1 C1 D1
2 A2 B2 C2 D2
3 A3 B3 C3 D3
4 A4 B4 C4 D4
5 A5 B5 C5 D5
6 A6 B6 C6 D6
7 A7 B7 C7 D7
8 A8 B8 C8 D8
9 A9 B9 C9 D9
10 A10 B10 C10 D10
11 A11 B11 C11 D11
0 A0 B0 C0 D0
1 NaN NaN NaN NaN
2 A2 B2 C2 D2
3 A3 B3 C3 D3
可以看到,在上面的示例中,我们得到了一个带有 NaN 值的 DataFrame。这是因为在 pd.concat() 合并多个 DataFrame 时,默认将缺失值填充为 NaN。
为了避免出现 NaN 值,有两种方法:
方法一:过滤 NaN
可以使用 .dropna() 方法在合并之前删除任何包含 NaN 的行或列。
比如,在本例中,我们在合并之前可以先删除任何包含 NaN 值的行:
df_concat = pd.concat([df1, df2, df3, df4.dropna()])
print(df_concat)
输出结果:
A B C D
0 A0 B0 C0 D0
1 A1 B1 C1 D1
2 A2 B2 C2 D2
3 A3 B3 C3 D3
4 A4 B4 C4 D4
5 A5 B5 C5 D5
6 A6 B6 C6 D6
7 A7 B7 C7 D7
8 A8 B8 C8 D8
9 A9 B9 C9 D9
10 A10 B10 C10 D10
11 A11 B11 C11 D11
0 A0 B0 C0 D0
2 A2 B2 C2 D2
3 A3 B3 C3 D3
这时候,我们把原来含有 NaN 值的 DataFrame df4 筛选出来,并使用 .dropna() 方法将其中含有 NaN 值的第 1 行删除。然后,我们将删除了 NaN 值的 DataFrame 与其他三个 DataFrame 进行合并,得到的结果就是一个没有 NaN 值的 DataFrame。
方法二:向前填充
使用 .fillna() 方法对存在 NaN 的数据框中的 NaN 值进行向前填充处理。
df_concat = pd.concat([df1, df2, df3, df4.fillna(method='ffill')])
print(df_concat)
输出结果:
A B C D
0 A0 B0 C0 D0
1 A1 B1 C1 D1
2 A2 B2 C2 D2
3 A3 B3 C3 D3
4 A4 B4 C4 D4
5 A5 B5 C5 D5
6 A6 B6 C6 D6
7 A7 B7 C7 D7
8 A8 B8 C8 D8
9 A9 B9 C9 D9
10 A10 B10 C10 D10
11 A11 B11 C11 D11
0 A0 B0 C0 D0
1 A0 B0 C0 D0
2 A2 B2 C2 D2
3 A3 B3 C3 D3
在这次的代码中,我们使用 fillna(method='ffill')
来向前填充数据,这意味着我们将 NaN 值替换为前面的值。这样,我们得到的 DataFrame 就没有 NaN 值了。
总结一下,要合并 DataFrame 时,如果其中存在缺失值,可以使用 .dropna() 方法或 .fillna() 方法来避免出现 NaN 值。在使用填充的方法时要注意,在处理缺失值时需要注意填充的顺序。