根据条件设置DataFrame的非空值
我有一个数据框:
0 1 2 3 4 y
35 NaN NaN NaN NaN 0.342153 0
40 NaN 0.326323 NaN NaN NaN 0
43 NaN NaN 0.290126 NaN NaN 0
49 NaN 0.326323 NaN NaN NaN 0
50 NaN 0.391147 NaN NaN NaN 1
还有生成它的代码:
import pandas as pd
import numpy as np
nan = np.nan
df = pd.DataFrame(
{0L: {35: nan, 40: nan, 43: nan, 49: nan, 50: nan},
1L: {35: nan,
40: 0.32632316859446198,
43: nan,
49: 0.32632316859446198,
50: 0.39114724480578139},
2L: {35: nan, 40: nan, 43: 0.29012581014105987, 49: nan, 50: nan},
3L: {35: nan, 40: nan, 43: nan, 49: nan, 50: nan},
4L: {35: 0.34215328467153283, 40: nan, 43: nan, 49: nan, 50: nan},
'y': {35: 0, 40: 0, 43: 0, 49: 0, 50: 1}})
我需要给每一列赋一个值,使用以下伪代码:
column = 1 if column > threshold else 0 where column != NaN
我尝试过用一些高级索引的方法来实现这个目标,像这样:
df.ix[df[1].notnull(),1] = 1; df
0 1 2 3 4 y
35 NaN NaN NaN NaN 0.342153 0
40 NaN 1 NaN NaN NaN 0
43 NaN NaN 0.290126 NaN NaN 0
49 NaN 1 NaN NaN NaN 0
50 NaN 1 NaN NaN NaN 1
但是A) 我不太确定怎么应用条件逻辑,B) 我必须对每一列逐个应用这个逻辑,而不是对整个数据框一起处理。
问题:
我该如何对数据框中非空的值应用条件逻辑,同时保留其他字段的空值状态呢?
3 个回答
1
你要找的是 iterrows()
这个方法。可以查看pandas的文档。
我不太确定你用伪代码想要实现什么,但下面的代码会修改新的系列(可以把它赋值给数据框)。
updated = df['data']
for index, row in df.iterrows():
if ((not pd.isnull(df[index])) and df[index] > threshold) :
updated[index] = 1.0
else:
updated[index] = 0.0
df['data'] = updated
这段代码很可能会给你一个 SettingWithCopyWarning
的警告,提示你在迭代器中赋值时要小心使用。
3
你可以使用 applymap
,因为看起来你真的想要逐个元素进行操作:
>>> df.applymap(lambda x: x if pd.isnull(x) else (1 if x > 0.3 else 0))
0 1 2 3 4 y
35 NaN NaN NaN NaN 1 0
40 NaN 1 NaN NaN NaN 0
43 NaN NaN 0 NaN NaN 0
49 NaN 1 NaN NaN NaN 0
50 NaN 1 NaN NaN NaN 1
虽然在这个特定的情况下,我们可以“作弊”(两次):
>>> (df > 0.3) * 1 + df * 0
0 1 2 3 4 y
35 NaN NaN NaN NaN 1 0
40 NaN 1 NaN NaN NaN 0
43 NaN NaN 0 NaN NaN 0
49 NaN 1 NaN NaN NaN 0
50 NaN 1 NaN NaN NaN 1
5
在编程中,有时候我们会遇到一些问题,比如代码运行不正常或者出现错误。这种时候,我们需要去查找原因,看看哪里出了问题。通常,我们可以通过查看错误信息来帮助我们找到问题所在。
错误信息就像是程序给我们的提示,它告诉我们哪里出错了,可能是什么原因导致的。理解这些信息可以帮助我们更快地解决问题。
另外,很多时候我们也可以在网上找到其他人遇到类似问题的解决方案,比如在StackOverflow这样的论坛上。这里有很多开发者分享他们的经验和解决方法,大家可以互相帮助。
总之,遇到问题时不要慌张,仔细查看错误信息,利用网络资源,通常都能找到解决办法。
# you need this because your y column is an int64 (otherwise this the next step
# will throw an exception), on the to fix list in 0.11-dev though
In [71]: df = orig_df.astype('float64')
# use boolean indexing!
# NaN are automatically excluded
In [72]: df[df>0.3] = 1 ; df[df<=0.3] = 0
In [73]: df
Out[73]:
0 1 2 3 4 y
35 NaN NaN NaN NaN 1 0
40 NaN 1 NaN NaN NaN 0
43 NaN NaN 0 NaN NaN 0
49 NaN 1 NaN NaN NaN 0
50 NaN 1 NaN NaN NaN 1