python 中vlookup的實現方法
本貼主要是作為一個記錄,防止優質部落格的丟失
請大家多多關注原帖:https://blog.csdn.net/htuhxf/article/details/84571404
https://stackoverflow.com/questions/25493625/vlookup-in-pandas-using-join
主要方法是使用merge或者map或者apply+lambda
文章目錄
merge
執行左合併,這將使用sku列作為要聯接的列:
In [26]:
df.merge(df1, on='sku', how='left')
Out[ 26]:
sku loc flag dept
0 122 61 True b
1 122 62 True b
2 122 63 False b
3 123 61 True b
4 123 62 False b
5 113 62 True a
6 301 63 True c
如果sku實際上是您的索引,請執行以下操作:
In [28]:
df.merge(df1, left_index=True, right_index=True, how='left')
Out[28]:
loc flag dept
sku
113 62 True a
122 61 True b
122 62 True b
122 63 False b
123 61 True b
123 62 False b
301 63 True c
另一種方法是使用map,如果將sku設定為第二個df的索引,那麼實際上它變成了一個系列,那麼程式碼簡化為:
In [19]:
df['dept']=df.sku.map(df1.dept)
df
Out[19]:
sku loc flag dept
0 122 61 True b
1 123 61 True b
2 113 62 True a
3 122 62 True b
4 123 62 False b
5 122 63 False b
6 301 63 True c
apply + lambda
另外一種方法是apply
和 lambda
dict1 = {113:'a',
122:'b',
123:'b',
301:'c'}
df = pd.DataFrame([['1', 113],
['2', 113],
['3', 301],
['4', 122],
['5', 113]], columns=['num', 'num_letter'])
新增為新的資料列
df['letter'] = df['num_letter'].apply(lambda x: dict1[x])
num num_letter letter
0 1 113 a
1 2 113 a
2 3 301 c
3 4 122 b
4 5 113 a
或替換現有的(‘num_letter’)列
df['num_letter'] = df['num_letter'].apply(lambda x: dict1[x])
num num_letter
0 1 a
1 2 a
2 3 c
3 4 b
4 5 a
merge的詳細介紹
第一、DataFrame.merge函式
更推薦使用merge()函式。簡單介紹點選這裡。
1) 函式部分:
pandas.merge
是pandas的全功能、高效能的的記憶體連線操作,在習慣上非常類似於SQL之類的關係資料庫。- 相較於其他開源軟體(如R中的
base::merge.data.frame
),pandas.merge
的效能要好得多(在某些情況下好得多一個數量級)。其原因是在DataFrame中優化的演算法設計和資料的內部佈局。
DataFrame.merge(
right, # 右DF,即要被merge的DataFrame
how='inner', # 取值有4個{‘left’, ‘right’, ‘outer’, ‘inner’}
on=None, left_on=None, right_on=None, # 如果使用左&右DF的公共欄位作為key,使用引數on;如果不使用左邊右邊的公共欄位作為key,使用引數left_on和right_on。
left_index=False, right_index=False, # 如果left_index=True,則left左邊DF的index(即索引的列名稱)是用來jion的keys。如果是MultiIndex,左DF和右DF的level數必須相等。right_index的作用與之相似。
sort=False, # 預設不對新合併表的結果按照字順序排序,可以節省運算時間。
suffixes=('_x', '_y'),
copy=True,
indicator=False, # 如果True,會新增一列,顯示資料的來源表名稱。
Validate=None # 是否檢查兩個merge的DFkeys是一對一關係、一對多關係,返回布林值( 'one_to_one'/ '1:1', 'one_to_many' / '1:m', 'many_to_one' / 'm:1')。預設情況下3種關係都可以,只是沒有輸出。
)
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
例子(注:要防止左右表的merge列同時存在空值,否則空值行的結果是笛卡爾積。例如,右邊m個座標n個空值,則左merge後,結果有n*m的控制行。)
- merge兩個DataFrame:
>>> A >>> B
lkey value rkey value
0 foo 1 0 foo 5
1 bar 2 1 bar 6
2 baz 3 2 qux 7
3 foo 4 3 bar 8
- 1
- 2
- 3
- 4
- 5
- 6
>>> A.merge(B, left_on='lkey', right_on='rkey', how='outer')
lkey value_x rkey value_y
0 foo 1 foo 5
1 foo 4 foo 5
2 bar 2 bar 6
3 bar 2 bar 8
4 baz 3 NaN NaN
5 NaN NaN qux 7
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- merge多個DataFrame與之類似,直接向後新增:
A.merge(B, right_on='col_r', left_on='col_l', how='outer').merge(C, right_on='col_r1', left_on='col_l1', how='outer')
- 1
EXCEL的
VLOOKUP()
函式不區分大寫小:
Python的merge()
函式區分大小寫:
left.merge(right, left_on='agent_name', right_on='agent_name1', how='left')
第二、map函式
2)例子部分:
- 資料:
import pandas as pd
data = pd.DataFrame({'food': ['bacon', 'pulled pork', 'bacon', 'Pastrami', 'corned beef', 'Bacon', 'pastrami', 'honey ham', 'nova lox'],
'ounces': [4, 3, 12, 6, 7.5, 8, 3, 5, 6]})
meat_to_animal = {
‘bacon’: ‘pig’,
‘pulled pork’: ‘pig’,
‘pastrami’: ‘cow’,
‘corned beef’: ‘cow’,
‘honey ham’: ‘pig’,
‘nova lox’: ‘salmon’}
print(data)
print(meat_to_animal)
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
對映關係:
- 要求:
– 在food表中,匹配出food是來源於那種animal的。
data['animal'] = data['food'].str.lower().map(meat_to_animal) # 利用對映表,新增列'animal'
print(data)
- 1
- 2
- 3
注: data['animal'] = data['food'].str.lower().map(meat_to_animal)
1)在“對映關係集合”不完整的情況下也能正常執行,取值NaN。比如這裡把 ‘pulled pork’: ‘pig’ 替換成 ‘blabla’: ‘pig’ 。
2)“對映關係集合”完整的情況下,可替換為 data['food'].map(lambda x: meat_to_animal[x.lower()])
。
但它在“對映關係集合”不完整的情況下報錯。