4

我有一个填充了 True 和 False 值的数据框,我想从中获取一个数据框,其中 True 替换为 1,False 替换为 np.NaN。我试过使用dataframe.replace,但它给了一个充满True的数据框。有没有办法在不使用 for 循环和 if 的情况下做到这一点?

例如,这是我拥有的数据框,T 表示 True,F 表示 False(不是字符串 'T' 和 'F';抱歉,无法弄清楚如何在 wiki 中格式化间隔良好的表格):

2008-01-02 16:00:00 TTF
2008-01-03 16:00:00 TTT
2008-01-04 16:00:00 TTF
2008-01-07 16:00:00 TTT
2008-01-08 16 :00:00 TTF

这就是我想将其更改为:

2008-01-02 16:00:00 1 1 np.NaN
2008-01-03 16:00:00 1 1 1
2008-01-04 16:00:00 1 1 np.NaN
2008-01-07 16: 00:00 1 1 1
2008-01-08 16:00:00 1 1 np.NaN

这些是我尝试替换 True 和 False 的行,并得到一个填充了所有 True 值的数据框:

df.replace(to_replace=True, value=1, inplace=True, method=None)   
df.replace(to_replace=False, value=np.NAN, inplace=True, method=None)  

单独尝试时,仅第一行不会改变任何东西;第二行将所有值转换为 True。

4

2 回答 2

9

applymap()可用于将函数应用于 a 的每个元素dataframe

In [1]: df = DataFrame([[True, True, False],[False, False, True]]).T

In [2]: df
Out[2]:
       0      1
0   True  False
1   True  False
2  False   True

In [3]: df.applymap(lambda x: 1 if x else np.nan)
Out[3]:
    0   1
0   1 NaN
1   1 NaN
2 NaN   1

您还可以使用dict

In [4]: d = {True:1, False:np.nan}

In [5]: df.applymap(lambda x: d[x])
Out[5]:
    0   1
0   1 NaN
1   1 NaN
2 NaN   1

从下面解决帝斯曼的评论。我误读了 OP 并假设日期时间是一个索引。如果它不是对我有用的索引:

In [6]: df.applymap(lambda x: d.get(x,x))
Out[6]:
    0   1                    2
0   1 NaN  2012-01-01 00:00:00
1 NaN   1  2012-01-01 00:00:00
于 2013-01-06T03:38:56.197 回答
1

尝试这个。where之所以有效,是因为默认情况下第一次使用nan会删除未找到的条目(例如,不是 == 'T' 的任何内容),然后第二次使用 1 替换未找到的条目

In [48]: df = pd.DataFrame([ 'T', 'T', 'T', 'F', 'F' ], columns=['value'],index=pd.date_range('20010101',periods=5))

In [49]: df
Out[49]: 
           value
2001-01-01     T
2001-01-02     T
2001-01-03     T
2001-01-04     F
2001-01-05     F

In [50]: df.where(df=='T').where(df!='T',1)
Out[50]: 
           value
2001-01-01     1
2001-01-02     1
2001-01-03     1
2001-01-04   NaN
2001-01-05   NaN
于 2013-01-06T16:43:29.560 回答