2017-10-11 155 views
1

我想根據其他列中的值將列添加到pandas DataFrame。根據其他列中的值將列添加到Python pandas DataFrame

import pandas as pd 
import numpy as np 

Records = 100 

df = pd.DataFrame (
     {'ID' : range(1, Records + 1), 
     'Group' : np.random.choice(range(1, 41), Records, replace = True) 
     } 
     ) 

def Age(x): 
    a = list() 
    for i in x: 
     if (i >= 14 and i <= 20) or (i >= 34 and i <= 40): 
      a.append('65+') 
     else: 
      a.append('65-') 
    return a 

df['Age'] = Age(df.Group) 

print(df.head(10)) 

    Group ID Age 
0  11 1 65- 
1  1 2 65- 
2  6 3 65- 
3  32 4 65- 
4  31 5 65- 
5  39 6 65+ 
6  26 7 65- 
7  38 8 65+ 
8  26 9 65- 
9  31 10 65- 

這樣做的工作,但我更喜歡使用lambda函數,如果可能但不能得到它的工作。或者如果可能的話,在創建數據框時創建Age列。有什麼建議麼?

回答

2

使用numpy.where什麼是非常快的矢量化功能:

m = ((df['Group'] >= 14) & (df['Group'] <= 20)) | ((df['Group'] >= 34) & (df['Group'] <= 40)) 
df['new'] = np.where(m, '65+','65-') 
print (df) 
    Group ID Age new 
0  11 1 65- 65- 
1  1 2 65- 65- 
2  6 3 65- 65- 
3  32 4 65- 65- 
4  31 5 65- 65- 
5  39 6 65+ 65+ 
6  26 7 65- 65- 
7  38 8 65+ 65+ 
8  26 9 65- 65- 
9  31 10 65- 65- 

時序

Records = 1000000 

In [94]: %timeit df['Age1'] = np.where((df['Group'] >= 14) & (df['Group'] <= 20) | (df['Group'] >= 34) & (df['Group'] <= 40), '65+','65-') 
10 loops, best of 3: 123 ms per loop 

In [95]: %timeit df['Age2'] = df['Group'].apply(lambda x: '65+' if ((x >= 14 and x <= 20) or (x >= 34 and x <= 40)) else '65-') 
1 loop, best of 3: 253 ms per loop 
1

隨着應用上df.Group系列

Records = 100 

df = pd.DataFrame (
     {'ID' : range(1, Records + 1), 
     'Group' : np.random.choice(range(1, 41), Records, replace = True) 
     } 
     ) 

#Here is the apply: 
df['Age'] = df['Group'].apply(lambda x: '65+' if ((x >= 14 and x <= 20) or 
                (x >= 34 and x <= 40)) else '65-') 
print(df.head()) 

結果:

Group ID Age 
0  3 1 65- 
1  25 2 65- 
2  6 3 65- 
3  23 4 65- 
4  20 5 65+ 
... 
2

選項1
重新考慮的條件。
請注意,兩個間隔都是寬度6
注意區間之間的中點是27

cats = np.array(['65-', '65+']) 
cond = df.Group.sub(27).abs().pipe(lambda x: x.ge(7) & x.le(13)).astype(int) 
df.assign(Age=cats[cond]) 

    Group ID Age 
0  11 1 65- 
1  1 2 65- 
2  6 3 65- 
3  32 4 65- 
4  31 5 65- 
5  39 6 65+ 
6  26 7 65- 
7  38 8 65+ 
8  26 9 65- 
9  31 10 65- 

我們可以通過使用基礎陣列

cats = np.array(['65-', '65+']) 
arr1 = np.abs(df.Group.values - 27) 
cond = ((arr1 >= 7) & (arr1 <= 13)).astype(int) 
df.assign(Age=cats[cond]) 

    Group ID Age 
0  11 1 65- 
1  1 2 65- 
2  6 3 65- 
3  32 4 65- 
4  31 5 65- 
5  39 6 65+ 
6  26 7 65- 
7  38 8 65+ 
8  26 9 65- 
9  31 10 65- 

選項2
使用np.searchsorted
使用[13, 20, 33, 40]整數斷點加快此起來。 searchsorted會告訴我們每個Group值落在哪裏,然後我們切片標籤數組,以給我們我們想要的。

b = np.array([13, 20, 33, 40]) 
c = np.array(['65-', '65+', '65-', '65+', '65-']) 
df.assign(Age=c[np.searchsorted(b, df.Group.values)]) 

    Group ID Age 
0  11 1 65- 
1  1 2 65- 
2  6 3 65- 
3  32 4 65- 
4  31 5 65- 
5  39 6 65+ 
6  26 7 65- 
7  38 8 65+ 
8  26 9 65- 
9  31 10 65- 
相關問題