在数据框列中查找字典的值并修改它
Find a value of a dictionary in dataframe column and modify it
我现在正在处理 DataFrames 和 Dictionaries,但遇到了问题,
我有一本字典“Fruits”
{BN:'Banana', LM:'Lemon', AP:'Apple' ..... etc}
还有一个 DataFrame- "Stock":
Fruit Price
0 Sweet Mango 1
1 Green Apple 2
2 Few blue Banana 0
3 Black Banana 5
我想做下一件事:
用 Fruits.values()
替换 Stock['Fruit']
中的所有值:
如果 Fruits 的值出现在 Stock['Fruit']
行中,它将被替换为:
小蓝香蕉--->香蕉
黑色香蕉色 ---> 香蕉色
现在 DataFrame Stock 看起来像这样:
Fruit Price
0 Sweet Mango 1
1 Green Apple 2
2 Banana 0
3 Banana 5
我找到了不同的代码来替换或检查字典中的值是否出现在 DataFrame 中
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())
但是我找不到任何东西来更新 DataFrame 的行
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)
使用答案 here 的结果,我们创建一个新的 class 子 class 是 defaultdict
,并将其 __missing__
属性覆盖为允许将密钥传递给 default_factory
:
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_factory
创建一个 class 的新实例。即,如果我们在搜索时没有找到键,则将键作为值放入。
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)
已接受的答案:
pat = r'({})'.format('|'.join(fruit_dict.values()))
%timeit df['Fruit'].str.extract(pat).fillna(df['Fruit'])
结果:
6.85 ms ± 223 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
我现在正在处理 DataFrames 和 Dictionaries,但遇到了问题, 我有一本字典“Fruits”
{BN:'Banana', LM:'Lemon', AP:'Apple' ..... etc}
还有一个 DataFrame- "Stock":
Fruit Price
0 Sweet Mango 1
1 Green Apple 2
2 Few blue Banana 0
3 Black Banana 5
我想做下一件事:
用 Fruits.values()
替换 Stock['Fruit']
中的所有值:
如果 Fruits 的值出现在 Stock['Fruit']
行中,它将被替换为:
小蓝香蕉--->香蕉
黑色香蕉色 ---> 香蕉色
现在 DataFrame Stock 看起来像这样:
Fruit Price
0 Sweet Mango 1
1 Green Apple 2
2 Banana 0
3 Banana 5
我找到了不同的代码来替换或检查字典中的值是否出现在 DataFrame 中
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())
但是我找不到任何东西来更新 DataFrame 的行
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)
使用答案 here 的结果,我们创建一个新的 class 子 class 是 defaultdict
,并将其 __missing__
属性覆盖为允许将密钥传递给 default_factory
:
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_factory
创建一个 class 的新实例。即,如果我们在搜索时没有找到键,则将键作为值放入。
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)
已接受的答案:
pat = r'({})'.format('|'.join(fruit_dict.values()))
%timeit df['Fruit'].str.extract(pat).fillna(df['Fruit'])
结果:
6.85 ms ± 223 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)