在Pandas DataFrame中更改特定值(存在混合类型)

4

我有一个pandas数据框,我希望在一些列中只增加大于零的值,并将其递增一个固定值(例如0.001)。

df=pd.DataFrame({'a': ['abc', 'abc', 'abc', 'abc'], 'b': [2,np.nan, 0, 6], 'c': [1, 0, 2, 0]})

     a    b  c
0  abc  2.0  1
1  abc  NaN  0
2  abc  0.0  2
3  abc  6.0  0

所以我尝试了这个:

df[df.loc[:,['b', 'c']]>0]+=1

TypeError: Cannot do inplace boolean setting on mixed-types with a non np.nan value

然而,由于第一列具有对象数据类型,因此我无法像您在错误中看到的那样执行此操作。期望的输出应该是:
     a    b      c
0  abc  2.001  1.001
1  abc  NaN    0
2  abc  0.0    2.001
3  abc  6.001  0

有没有一种方法可以在不分别循环每个列的情况下完成这种操作?
我相信我只是缺少一个简单的方法,但似乎找不到一个示例。
3个回答

4
你可以尝试这个方法:
import pandas as pd
import numpy as np

df = pd.DataFrame({'a': ['abc', 'abc', 'abc', 'abc'], 
                   'b': [2,np.nan, 0, 6], 
                   'c': [1, 0, 2, 0]})

inc = 0.01
df.loc[:, df.dtypes.ne('object')] += inc
df.replace({inc:0}, inplace=True)        

print(df)

或者按照 Tai 的建议使用 np.where(这样应该更快):
cols = df.columns[df.dtypes.ne('object')]
df[cols] += np.where(df[cols] >0, 0.01, 0)

返回:

     a     b     c
0  abc  2.01  1.01
1  abc   NaN  0.00
2  abc  0.00  2.01
3  abc  6.01  0.00

谢谢评论。然而,这也会增加零的数量。您如何只考虑值> 0? - campo
1
@jpp 感谢提到 select_dtypes,我借鉴了它 :-) - BENY
@campo 是的,这是一个 hack。但它比 Wen 建议的 df = pd.concat([df]*1000) 上的 df.add() 更快。 - Anton vBR
1
@Tai 是的,我认为那是最通用和可读的。我试图用 .loc 应用它。 - Anton vBR
对于这个问题,请注意如果边界不为0,则使用replace会产生一些麻烦(例如限制0.01,然后添加值0.01)@campo - BENY
显示剩余4条评论

3
您可以使用 select_dtypesadd 来完成此操作。
df.add((df.select_dtypes(exclude=object)>0).astype(int)*0.0001).combine_first(df)
Out[18]: 
     a       b       c
0  abc  2.0001  1.0001
1  abc     NaN  0.0000
2  abc  0.0000  2.0001
3  abc  6.0001  0.0000

谢谢,但现在“a”列全部是NaN。 - campo
@campo 添加 combine_first :-) - BENY
非常聪明!非常感谢Wen。似乎您也不需要将其转换为整数: df.add((df.select_dtypes(exclude=object)>0)*.001).combine_first(df) - campo
@campo 是的,我们不需要那一步 :-) - BENY

2

您只能添加列bc

df[["b", "c"]] += np.where(df[["b", "c"]] > 0, 0.01, 0)

我们使用np.where来填充0以绕过数据中的np.nan

Anton vBR有一种优雅的方法来选择所需的列。


是的,这正是我在寻找的。 - Anton vBR

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