Python 在dataframe列中查找字典的值并修改它
我现在正在处理数据帧和字典,我有一个问题, 我有一本字典“水果” 和一个数据帧——“股票”: 我想做下一件事: 用Python 在dataframe列中查找字典的值并修改它,python,pandas,dictionary,dataframe,any,Python,Pandas,Dictionary,Dataframe,Any,我现在正在处理数据帧和字典,我有一个问题, 我有一本字典“水果” 和一个数据帧——“股票”: 我想做下一件事: 用Fruits.values()替换库存['Fruit']中的所有值,方法如下: 如果来自水果的值出现在Stock['Fruit']行中,它将以以下方式替换: Fruit Price 0 Sweet Mango 1 1 Green Apple 2 2 Banana 0 3 Ban
Fruits.values()
替换库存['Fruit']中的所有值,方法如下:
如果来自水果的值出现在Stock['Fruit']
行中,它将以以下方式替换:
Fruit Price
0 Sweet Mango 1
1 Green Apple 2
2 Banana 0
3 Banana 5
很少有蓝色的香蕉-->香蕉
黑色香蕉-->香蕉
现在,DataFrame库存将如下所示:
Fruit Price
0 Sweet Mango 1
1 Green Apple 2
2 Banana 0
3 Banana 5
我找到了不同的代码来替换或检查数据帧中是否出现了来自dictionary的值
Stock['Fruit'] = Stock.Fruit.map(Fruits)
if (Fruits.values() in Stock['Fruit'] for item in Stock)
any('Mango' in Stock['Fruit'] for index,item in Stock.iterrows())
但是我找不到任何东西来更新数据框的行,您可以使用带有自定义函数的
apply()
:
Stock['Fruit'] = Stock.Fruit.map(Fruits)
if (Fruits.values() in Stock['Fruit'] for item in Stock)
any('Mango' in Stock['Fruit'] for index,item in Stock.iterrows())
import pandas as pd
df = pd.DataFrame([['Sweet Mango', 1],['Green Apple', 2],['Few blue Banana', 0],['Black Banana', 5]],
columns=['Fruit','Price'])
fruits = {'BN':'Banana', 'LM': 'Lemon', 'AP':'Apple', 'MG': 'Mango'}
def find_category(x):
return [k for k in fruits.values() if k in x][0]
df['Fruit'] = df['Fruit'].apply(find_category)
收益率:
Fruit Price
0 Mango 1
1 Apple 2
2 Banana 0
3 Banana 5
IIUC,您可以将
apply()
与自定义函数一起使用:
import pandas as pd
df = pd.DataFrame([['Sweet Mango', 1],['Green Apple', 2],['Few blue Banana', 0],['Black Banana', 5]],
columns=['Fruit','Price'])
fruits = {'BN':'Banana', 'LM': 'Lemon', 'AP':'Apple', 'MG': 'Mango'}
def find_category(x):
return [k for k in fruits.values() if k in x][0]
df['Fruit'] = df['Fruit'].apply(find_category)
收益率:
Fruit Price
0 Mango 1
1 Apple 2
2 Banana 0
3 Banana 5
对条件和提取所需值使用字符串方法
pat = r'({})'.format('|'.join(d.values()))
cond = df['Fruit'].str.contains('|'.join(d.values()))
df.loc[cond, 'Fruit'] = df['Fruit'].str.extract((pat), expand = False)
Fruit Price
0 Sweet Mango 1
1 Apple 2
2 Banana 0
3 Banana 5
编辑:正如@user3483203所建议的,一旦提取模式,您就可以用原始值填充缺少的值
df['Fruit'] = df['Fruit'].str.extract(pat).fillna(df.Fruit)
对条件和提取所需值使用字符串方法
pat = r'({})'.format('|'.join(d.values()))
cond = df['Fruit'].str.contains('|'.join(d.values()))
df.loc[cond, 'Fruit'] = df['Fruit'].str.extract((pat), expand = False)
Fruit Price
0 Sweet Mango 1
1 Apple 2
2 Banana 0
3 Banana 5
编辑:正如@user3483203所建议的,一旦提取模式,您就可以用原始值填充缺少的值
df['Fruit'] = df['Fruit'].str.extract(pat).fillna(df.Fruit)
使用答案的结果,我们创建了一个新类,该类子类为
defaultdict
,并覆盖其\uuuuuu missing\uuuuu
属性,以允许将密钥传递到默认工厂
:
from collections import defaultdict
class keydefaultdict(defaultdict):
def __missing__(self, key):
if self.default_factory is None:
raise KeyError(key)
else:
ret = self[key] = self.default_factory(key)
return ret
我们创建了一个初始字典,用于映射要替换的'Fruits'
列中的2个值
fruit_dict = {'Few blue Banana': 'Banana', 'Black Banana': 'Banana'}
然后我们用lambda x:x
的default\u工厂创建一个类的新实例。也就是说,如果我们在搜索时找不到该键,请将该键作为值输入
fruit_col_map = keydefaultdict(lambda x: x)
fruit_col_map.update(**fruit_dict)
最后,更新列:
df['Fruit'] = df['Fruit'].map(fruit_col_map)
df
输出:
Fruit Price
0 Sweet Mango 1
1 Green Apple 2
2 Banana 0
3 Banana 5
与公认的答案相比,这要快6倍多:
df = pd.DataFrame({
'Fruit': ['Sweet Mango', 'Green Apple', 'Few blue Banana', 'Black Banana']*1000,
'Price': [1, 2, 0, 5]*1000
})
%timeit df['Fruit'].map(fruit_col_map)
结果:
1.03 ms ± 48.5 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
6.85 ms ± 223 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
接受的答复:
pat = r'({})'.format('|'.join(fruit_dict.values()))
%timeit df['Fruit'].str.extract(pat).fillna(df['Fruit'])
结果:
1.03 ms ± 48.5 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
6.85 ms ± 223 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
使用答案的结果,我们创建了一个新类,该类子类为defaultdict
,并覆盖其\uuuuuu missing\uuuuu
属性,以允许将密钥传递到默认工厂
:
from collections import defaultdict
class keydefaultdict(defaultdict):
def __missing__(self, key):
if self.default_factory is None:
raise KeyError(key)
else:
ret = self[key] = self.default_factory(key)
return ret
我们创建了一个初始字典,用于映射要替换的'Fruits'
列中的2个值
fruit_dict = {'Few blue Banana': 'Banana', 'Black Banana': 'Banana'}
然后我们用lambda x:x
的default\u工厂创建一个类的新实例。也就是说,如果我们在搜索时找不到该键,请将该键作为值输入
fruit_col_map = keydefaultdict(lambda x: x)
fruit_col_map.update(**fruit_dict)
最后,更新列:
df['Fruit'] = df['Fruit'].map(fruit_col_map)
df
输出:
Fruit Price
0 Sweet Mango 1
1 Green Apple 2
2 Banana 0
3 Banana 5
与公认的答案相比,这要快6倍多:
df = pd.DataFrame({
'Fruit': ['Sweet Mango', 'Green Apple', 'Few blue Banana', 'Black Banana']*1000,
'Price': [1, 2, 0, 5]*1000
})
%timeit df['Fruit'].map(fruit_col_map)
结果:
1.03 ms ± 48.5 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
6.85 ms ± 223 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
接受的答复:
pat = r'({})'.format('|'.join(fruit_dict.values()))
%timeit df['Fruit'].str.extract(pat).fillna(df['Fruit'])
结果:
1.03 ms ± 48.5 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
6.85 ms ± 223 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
为什么绿苹果
没有被苹果
取代?我刚才举了一个我想要的例子,我问你为什么不把绿苹果
改成苹果
,但是你把黑香蕉
改成香蕉
,在你的输出上面,我的答案包括你想要的输出吗?如果没有,你能澄清你想要的完整输出是什么吗?Green Apple
为什么没有被Apple
取代?我只是举了一个我想要的例子,我想问你为什么不把Green Apple
改成Apple
,但是您确实在上面的输出中将黑香蕉
更改为香蕉
,我的答案是否包括您想要的输出?如果没有,你能澄清你想要的完整输出是什么吗?或者干脆df.Fruit.str.extract(pat).fillna(df.Fruit)
。您也不需要指定expand=False
,因为您只有一个捕获组,或者只有df.Fruit.str.extract(pat).fillna(df.Fruit)
。您也不需要指定expand=False
,因为您只有一个捕获组,如果处理较大的数据帧,“apply()”将是最有效的。@rahlf23 tnx,它适用于我作为示例提供的数据帧和字典,现在我尝试用另一个来实现这一点,还有一个问题:新字典states={'OH':'OH':'KY':'Kentucky','AS':'American Samoa','NV':'Nevada'…}
和一个列为'State and Region'的数据框。State也包含了一些我想用一个词替换的词。当我复制了你的代码并只更改了变量时,它给了我一个错误:--->5返回[k代表k在states.values()如果k在x][0]索引器:列表索引超出范围
当我删除[0]
@rahlf23当我删除[0]
时,它给了我一个“良好”的数据帧,但接下来的问题是:`State RegionName 0[]奥本1[阿拉巴马州]佛罗伦萨2[]杰克逊维尔3[阿拉巴马州]利文斯顿4[]蒙特瓦洛5[]特洛伊6[阿拉巴马州]塔斯卡卢萨7[]塔斯基吉8[阿拉斯加州]费尔班克斯9[亚利桑那州]弗拉格斯塔夫`正如你所见,它跳过了一些值,并添加了“[]”全体others@JLuxton我使用的那个要大得多,我只是用小的=)@B.Kristina练习过。如果字典中的值没有精确匹配,这个解决方案将返回[]
。使用[0]
的原因是返回第一个匹配(因为我假设您的值是唯一的,并且对多个键无效)。如果删除[0]
,则它将返回包含该值的键列表。'apply()“如果处理更大的数据帧,将是最有效的。@rahlf23 tnx,它适用于我给出的数据帧和字典作为示例,现在我尝试使用另一个字典,但有一个问题:新字典states={'OH':'oho','KY':'Kentucky','as':'American Samoa','NV':'Nevada'…}
和列为“State and Region”的数据帧状态中也包含一些我想用一个词替换的词。当我复制了你的代码,只更改了变量时,它给了我一个错误:--->5返回[k代表状态中的k