2016-11-04 28 views
1

我正在使用的代碼波紋管來編碼的數據集:NANS上pd.factorize返回對象

foo= pd.DataFrame({ 
        'Col1' : ['B', 'A', 'B', 'C', 'B', 'A', 'C'], 
        'Val' : np.random.randn(7) 
        }) 
r=pd.factorize(foo['Col1'], sort=True) 
foo['Col1'] = r[0] 

其中(前後\)產生以下正確的結果:

Col1  Val   Col1  Val 
    B 0.094336    1 0.094336 
    A -0.422168    0 -0.422168 
    B -0.750304    1 -0.750304 
    C 1.910625    2 1.910625 
    B 0.921890    1 0.921890 
    A 0.422612    0 0.422612 
    C -1.130780    2 -1.130780 


print r 
(array([1, 0, 1, 2, 1, 0, 2]), Index([u'A', u'B', u'C'], dtype='object')) 

和(因爲「排序」),我也可以通過運行之間建立起鍵\值映射功能 - 這是我的目標:

zip(np.unique(r[0]), r[1]) 
[(0, 'A'), (1, 'B'), (2, 'C')] # A became 0; B became 1 and so on... 

我的問題我。那時我對數據集NaN,並且他們得到-1(這是我想要的東西 - 它必須是-1):

foo= pd.DataFrame({ 
        'Col1' : ['B', 'A', 'B', 'C', 'B', 'A', np.nan], 
        'Val' : np.random.randn(7) 
        }) 

r=pd.factorize(foo['Col1'], sort=True) 
foo['Col1'] = r[0] 


Col1  Val   Col1  Val 
    B 1.397748   1 1.397748 
    A -1.011483   0 -1.011483 
    B 0.679650   1 0.679650 
    C 0.861900   2 0.861900 
    B -0.430241   1 -0.430241 
    A 1.472984   0 1.472984 
NaN 0.549857   -1 0.549857 

但pd.factorize沒有在返回的「楠」索引:

print r[1] 
Index([u'A', u'B', u'C'], dtype='object') 

,現在我的映射功能不起作用:

zip(np.unique(r[0]), r[1]) 
Out[148]: [(-1, 'A'), (0, 'B'), (1, 'C')] 

任何方式使pd.factorize函數返回楠其索引的對象呢?

感謝

回答

1

如果你能保證在r[0]一個-1唯一的原因就是在你的數據集np.nan,那麼你可以用下面的函數所需的映射:

def get_mapping(r): 
    if -1 in r[0]: 
     return zip(np.unique(r[0]), r[1].insert(0, np.nan)) 
    else: 
     return zip(np.unique(r[0]), r[1]) 
2

由於列中包含float + str的dtypes,其中存在Nanspd.factorize在分配值-1(缺省值)後排除了缺失值。

另一種方法是計算系列中存在的唯一值,然後將其轉換爲categorical dtype,該值還通過codes屬性爲Nans分配值-1。

演示:

ser = pd.Series(foo['Col1'].unique(), dtype='category') 
ser 
Out[125]: 
0  B 
1  A 
2  C 
3 NaN 
dtype: category 
Categories (3, object): [A, B, C] 

print(list(zip(ser, ser.cat.codes))) 
#[('B', 1), ('A', 0), ('C', 2), (nan, -1)]