如何在 pandas 中移除 NaN 值并压缩 DataFrame

3

我在编写代码时意识到,我认为有更简单的方法可以完成这项任务。

所以我有一个像这样的DataFrame

>>> df = pd.DataFrame({'a': [1, 'A', 2, 'A'], 'b': ['A', 3, 'A', 4]})
   a  b
0  1  A
1  A  3
2  2  A
3  A  4

我想从数据中删除所有的 A,但我也想在 DataFrame 中挤压,我的意思是要得到这样的结果:

   a  b
0  1  3
1  2  4

我有一个以下解决方案:

a = df['a'][df['a'] != 'A']
b = df['b'][df['b'] != 'A']
df2 = pd.DataFrame({'a': a.tolist(), 'b': b.tolist()})
print(df2)

这个方法是可行的,但我认为还有更简单的方式。我已经停止编码一段时间了,不太聪明了...

注:

所有列都有相同数量的A,这里没有问题。


你能确定每个系列都有相等数量的“A”吗?否则,你可能会出现长度不匹配的情况。你也可以使用“df.replace('A', np.Nan, inplace=True)”代替你的两个条件。 - BenP
@BenP 是的,你说得对,我会进行编辑。 - U13-Forward
1
@BenP 我修改了我的。 - U13-Forward
假设列数为2,'A'恰好在其替换值的上方,则翻译后的内容为:pd.DataFrame(df.to_numpy()[df.to_numpy()!="A"].reshape(-1, 2), columns = df.columns) - sammywemmy
3个回答

3
你可以尝试使用 loc 进行布尔索引来删除 A 值:
pd.DataFrame({c: df.loc[df[c] != 'A', c].tolist() for c in df})

结果:

   a  b
0  1  3
1  2  4

2
这样做就可以了:
In [1513]: df.replace('A', np.nan).apply(lambda x: pd.Series(x.dropna().to_numpy()))
Out[1513]: 
     a    b
0  1.0  3.0
1  2.0  4.0

嗯,这个DataFrame看起来很适合。如果你也有原始数据列表,你可以使用lambda或列表推导式和过滤器。 - BenP
重构怎么样?这很干净:pd.DataFrame({c: df[c].replace('A', np.nan).dropna().to_numpy() for c in df}) - cs95

2
我们可以使用df.melt函数,然后筛选掉'A'的值,再使用df.pivot函数。
out = df.melt().query("value!='A'")
out.index = out.groupby('variable')['variable'].cumcount()
out.pivot(columns='variable', values='value').rename_axis(columns=None)

   a  b
0  1  3
1  2  4

细节

out = df.melt().query("value!='A'")

 variable value
0        a     1
2        a     2
5        b     3
7        b     4

# We set this as index so it helps in `df.pivot`
out.groupby('variable')['variable'].cumcount()

0    0
2    1
5    0
7    1
dtype: int64

out.pivot(columns='variable', values='value').rename_axis(columns=None)

   a  b
0  1  3
1  2  4

另一种选择
df = df.mask(df.eq('A'))
out = df.stack()
pd.DataFrame(out.groupby(level=1).agg(list).to_dict())

   a  b
0  1  3
1  2  4

细节

df = df.mask(df.eq('A'))

     a    b
0    1  NaN
1  NaN    3
2    2  NaN
3  NaN    4

out = df.stack()

0  a    1
1  b    3
2  a    2
3  b    4
dtype: object

pd.DataFrame(out.groupby(level=1).agg(list).to_dict())

   a  b
0  1  3
1  2  4

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接