我有一个Pandas数据框,其中包含A列和B列
Sub InsertClient()
lastrow = Cells(Rows.Count, "A").End(xlUp).Row
For i = lastrow To 2 Step -1
If i = lastrow Then
Range("A" & i + 1).Value = Range("A" & i).Value
End If
If Range("A" & i).Value <> Range("A" & i - 1).Value Then
Rows(i).Insert shift:=xlShiftDown
Range("A" & i).Value = Range("A" & i - 1).Value
End If
Next i
End Sub
我创建了列C,如果import pandas as pd
import numpy as np
df = pd.DataFrame(np.random.randint(0,100,size=(10, 2)), columns=list('AB'))
A > B
这给出了:
df['C'] = np.select([ df.A > df.B ], [df.A], default=np.NaN)
然后,我使用以下几种方法之一删除具有df.C作为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 = df.dropna(subset=['C'], how='any')
或
df = df.drop(df[pd.isnull(df.C)].index)
并且所有3种方法都让我大致有行。在这种情况下:
df = df.drop(df[(pd.isnull(df.C))].index)
但是当我不使用数字时,例如字符串:
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为NaN的行的3种方法。例如,当df['C'] = np.select([ df.A > df.B ], ['yes'], default=np.NaN)
将C列设置为df.A > df.B
时,我会得到类似的结果:
yes
我可以解决这个问题,将pd.NaN替换为&#39; IGNORE&#39;等字符串,然后过滤&#39; IGNORE&#39;,但我发现这个结果是出乎意料的。
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
这里发生了什么? (当df.C是一个字符串时,我的pd.NaN被转换为字符串吗?)
我在Windows 10上使用64位Python 2.7.13,Pandas 0.19.2和Numpy 1.11.3。
答案 0 :(得分: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
答案 1 :(得分: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更喜欢单个数据类型,所以当数组中有一个字符串元素时,所有元素都转换为字符串。
对于您的情况,如果您有字符串列,则可以使用None
代替np.nan
作为默认值,这将创建一个缺失值,可以通过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