我有一个DataFrame
像这样:
>>> df = pd.DataFrame({'a': list('ABCD'), 'b': ['E',np.nan,np.nan,'F']})
a b
0 A E
1 B NaN
2 C NaN
3 D F
我正在尝试填写NaN
将前一列的值放入下一行并删除第二行。换句话说,我想将两行与 NaN 组合起来形成没有 NaN 的单行,如下所示:
a b
0 A E
1 B C
2 D F
我尝试过各种口味的df.fillna(method="<bfill/ffill>")
但这并没有给我预期的输出。
我还没有发现任何关于这个问题的其他问题,Here's一。实际上DataFrame
由 list of DataFrame
制成通过这样做.concat()
,您也可能会从索引中注意到这一点。我之所以这么说,是因为单行比多行更容易做到。
我发现了一些使用 shift
的建议, combine_first
但他们都不为我工作。您也可以尝试这些。
我还发现了this也。这是一篇关于填充的整篇文章nan
值,但我还没有找到像我这样的问题/答案。
最佳答案
好吧,我第一次误解了你想要做什么。虚拟示例有点含糊。
这是另一个:
>>> df = pd.DataFrame({'a': list('ABCD'), 'b': ['E',np.nan,np.nan,'F']})
a b
0 A E
1 B NaN
2 C NaN
3 D F
据我所知,pandas 不存在此操作,因此我们将使用 numpy 来完成这项工作。
首先将数据帧转换为 numpy 数组和 flatten
它是一维的。然后使用 pandas.isna
删除 NaN正在处理比 numpy.isnan
更大的范围类型,然后 reshape
在转换回数据帧之前将数组恢复到其原始形状:
array = df.to_numpy().flatten()
pd.DataFrame(array[~pd.isna(array)].reshape(-1,df.shape[1]), columns=df.columns)
输出:
a b
0 A E
1 B C
2 D F
它也适用于更复杂的示例,只要 NaN 模式在具有 NaN 的列之间保持不变:
In:
a b c d
0 A H A2 H2
1 B NaN B2 NaN
2 C NaN C2 NaN
3 D I D2 I2
4 E NaN E2 NaN
5 F NaN F2 NaN
6 G J G2 J2
Out:
a b c d
0 A H A2 H2
1 B B2 C C2
2 D I D2 I2
3 E E2 F F2
4 G J G2 J2
In:
a b c
0 A F H
1 B NaN NaN
2 C NaN NaN
3 D NaN NaN
4 E G I
Out:
a b c
0 A F H
1 B C D
2 E G I
如果 NaN 列没有相同的模式,例如:
a b c d
0 A H A2 NaN
1 B NaN B2 NaN
2 C NaN C2 H2
3 D I D2 I2
4 E NaN E2 NaN
5 F NaN F2 NaN
6 G J G2 J2
您可以对每组两列应用该操作:
def elementwise_shift(df):
array = df.to_numpy().flatten()
return pd.DataFrame(array[~pd.isna(array)].reshape(-1,df.shape[1]), columns=df.columns)
(df.groupby(np.repeat(np.arange(df.shape[1]/2), 2), axis=1)
.apply(elementwise_shift)
)
输出:
a b c d
0 A H A2 B2
1 B C C2 H2
2 D I D2 I2
3 E F E2 F2
4 G J G2 J2
关于python - 如何按元素移动数据帧以填充 NaN?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68479177/