2017-02-17 175 views
3

将行我有一个熊猫数据帧的列A和BPython的大熊猫 - 基于价值

import pandas as pd 
import numpy as np 

df = pd.DataFrame(np.random.randint(0,100,size=(10, 2)), columns=list('AB')) 

我创建列C,这是NULL,如果A > B

df['C'] = np.select([ df.A > df.B ], [df.A], default=np.NaN) 

这给:

A B  C 
0 95 19 95.0 
1 46 11 46.0 
2 96 86 96.0 
3 22 61 NaN 
4 69 1 69.0 
5 78 91 NaN 
6 42 7 42.0 
7 24 28 NaN 
8 55 92 NaN 
9 92 16 92.0 

然后,我使用以下几种方法之一删除具有df.C作为NaN的行:

df = df.dropna(subset=['C'], how='any') 

df = df.drop(df[pd.isnull(df.C)].index) 

df = df.drop(df[(pd.isnull(df.C))].index) 

和所有3种方法给我大致都行。在这种情况下:

A B  C 
0 95 19 95.0 
1 46 11 46.0 
2 96 86 96.0 
4 69 1 69.0 
6 42 7 42.0 
9 92 16 92.0 

但是,当我不使用一个号码,例如一个字符串:

df['C'] = np.select([ df.A > df.B ], ['yes'], default=np.NaN) 

然后这些相同的3种方法与df.C是NaN的下跌行进行过滤。例如,当df.A > df.B组列C至yes,我得到的是这样的:

A B C 
0 6 70 nan 
1 85 46 yes 
2 76 87 nan 
3 77 36 yes 
4 73 18 yes 
5 1 41 nan 
6 19 69 nan 
7 62 89 nan 
8 6 7 nan 
9 35 75 nan 

我可以解决这个问题,通过与像“忽略”,一个字符串替换pd.NaN然后过滤“忽略”,但我发现这个结果,否则意外。

df['C'] = np.select([ df.A > df.B ], ['yes'], default='IGNORE') 
df = df.drop(df[(df.C == 'IGNORE')].index) 

这是怎么回事? (当df.C是一个字符串,是我pd.NaN的被转换为字符串?)


我使用的是64位的Python 2.7.13,熊猫0.19.2和1.11.3 NumPy的Windows 10.

+0

@Psidom是的,没错。看起来NaN实际上是“不是数字”,并且正在转换为字符串“nan”。 – philshem

+0

@Psidom如果你写你的评论作为答案我会很乐意接受它。它并没有真正解释为什么,但它肯定解决了这个问题 – philshem

回答

1

你的情况是类似的到这一个:

np.array([1,2,'3',np.nan]) 
# array(['1', '2', '3', 'nan'], 
#  dtype='<U21') 

因为np.select还返回一个数组,如果进一步检查

type(np.nan) 
# float 

str(np.nan) 
# 'nan' 

所以np.nan是浮动的,但numpy的阵列更喜欢单个数据类型,除了structured array,所以当在阵列中的字符串元素,所有元素被转换为字符串。


对于你的情况,如果你有字符串列,可以代替np.nan使用None为默认值,这将创建一个缺失值可以通过isnull()检查和工作原理与dropna()

import pandas as pd 
import numpy as np 
​ 
df = pd.DataFrame(np.random.randint(0,100,size=(10, 2)), columns=list('AB')) 
df['C'] = np.select([ df.A > df.B ], ['yes'], default=None) 

df.dropna() 

# A B  C 
#0 82 1 yes 
#3 84 8 yes 
#6 52 30 yes 
#7 68 61 yes 
#9 91 87 yes 
2

而不是丢弃,只取有限值。

df = df[np.isfinite(df['C'])] 

编辑:

按照你对此有何评论nan是类型string,因此,删除基于值的行:

df = df[df.C != "nan"]将工作

df[df.C.notnull()] 
    A B C 
0 67 23 yes 
1 91 61 yes 
2 30 92 nan 
3 53 97 nan 
4 81 11 yes 
5 23 7 yes 
6 47 39 yes 
7 11 27 nan 
8 46 55 nan 
9 31 82 nan 
df = df[df.C != "nan"] 


    A B C 
0 67 23 yes 
1 91 61 yes 
4 81 11 yes 
5 23 7 yes 
6 47 39 yes 
+0

我得到了一个TypeError'ufunc'isfinite'不支持输入类型,并且输入不能被安全地强制转换为任何支持的类型。 safe''' – philshem

+0

我试图模拟你的问题和解决方案。导入numpy为np import pandas as pd df = pd.DataFrame(np.random.randint(0,100,size =(10,2)),columns = list('AB')) df ['C'] = np.select([df.A> df.B],[df.A],默认= np.NaN) 打印DF ABC 0 81 17 81.0 1 14 67 NaN的 2 16 9 16.0 3 25 31为NaN 4 35 36 NaN的 5 56 5 56.0 6 18 20 NaN的 7 32 4 32.0 8 46 51的NaN 9 53 34 53.0 DF = DF [np.isfinite(DF [ 'C')] 打印DF ABC 0 81 17 81.0 2 16 9 16.0 5 56 5 56.0 7 32 4 32.0 9 53 34 53.0 –

+0

好的不同之处在于,在我的实际代码中(而不是我在此处发布的示例代码),请尝试:'df ['C'] = np。选择([df.A> df.B],[u'yes'],default = np.NaN)' – philshem