本贴主要是作为一个记录,防止优质博客的丢失
请大家多多关注原帖: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()])
。
但它在“映射关系集合”不完整的情况下报错。