5

我有一个数据框:

     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)我必须将逻辑迭代地应用到每一列而不是整个数据框。

问题:

如何将条件逻辑应用于数据帧的非空值,同时保留其他字段的空值?

4

3 回答 3

5
# 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
于 2013-03-13T18:05:03.507 回答
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
于 2013-03-13T18:15:23.893 回答
1

您正在寻找的是iterrows()方法。熊猫文档

我不是 100% 确定你试图用伪代码完成什么,但下面会修改新系列(可以分配给数据框)。

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在迭代器中向您发出有关分配的警告,因此请谨慎使用。

于 2015-11-06T20:36:53.520 回答