在数据框列中查找字典的值并修改它

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: xdefault_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)