循环遍历数据帧列以检查字典键

时间:2017-08-02 21:32:20

标签: python python-3.x pandas dataframe

大家好,我有一个数据框:

df1
   WM          WH         WP           LC_REF
0 Tesla     Doritos     Spiders        DT 17 1C
1 Merc      Lays        Contortion     DT 17 1C
2 Lambo     Finale        NaN          DT 17 1C
3 Reddy       Red         NaN          DT 17 1C
4 Tomball     Fools       NaN          DT 17 1C

和字典

example = {'Fools':'Car','Red':'Car','Merc':'Car','Tesla':'Car','Doritos':'Food','Spiders':'Food','Reddy':'Food','Tomball':'Food'}

我想知道检查每列中每个项目的最有效方法,然后对列进行分组,这样如果列值与值'Car'或'Food'匹配,那么所需的输出是:

df2 if key matches Car

  LC_REF    vals        Category
0 DT 17 1C  Merc,Tesla    WM
1 DT 17 1C  Red, Fools    WH


df3 if key matches Food

  LC_REF    vals                 Category
0 DT 17 1C  Reddy,Tomball          WM
1 DT 17 1C  Doritos, Lays          WH
2 DT 17 1C  Spiders, Contortion    WP

到目前为止

df = df.groupby('LC_REF',sort=False).agg(lambda x: ','.join(x.astype(str).str.upper()).replace(' ','')).stack().rename_axis(('LC_REF','a')).reset_index(name='vals')

是我的分组代码,但我正在努力如何正确地分开它们。对这个复杂问题的任何帮助都会很棒。

1 个答案:

答案 0 :(得分:1)

尝试以下方法:

import pandas as pd
import io


example = {'Fools':'Car','Red':'Car','Merc':'Car',
           'Tesla':'Car','Doritos':'Food',
           'Spiders':'Food','Reddy':'Food',
           'Tomball':'Food', 'Lays':'Food', 'Contortion': 'Food'}

# Flip the example dictionary around (keys become values and values become keys)
value_dict = {}
for k, v in example.items():
    value_dict.setdefault(v, [])
    value_dict[v].append(k)

text = u"""WM          WH         WP           LC_REF
Tesla     Doritos     Spiders       DT 17 1C
Merc      Lays        Contortion    DT 17 1C
Lambo     Finale        NaN         DT 17 1C
Reddy       Red         NaN         DT 17 1C
Tomball     Fools       NaN         DT 17 1C"""

df1 = pd.read_table(io.StringIO(text), header=0, sep="\s{2,}", engine='python')
# Melt the dataframe first
df2 = pd.melt(df1, id_vars=['LC_REF'], value_name='vals', var_name='Category')

# Get your dataframe for Food
food_df = df2.loc[df2.vals.isin(value_dict.get('Food'))].groupby(['LC_REF', 'Category']).apply(lambda x: ', '.join(x.vals)).reset_index()
print(food_df)

#      LC_REF Category                    0
# 0  DT 17 1C       WH        Doritos, Lays
# 1  DT 17 1C       WM       Reddy, Tomball
# 2  DT 17 1C       WP  Spiders, Contortion

# Get your dataframe for Car
car_df = df2.loc[df2.vals.isin(value_dict.get('Car'))].groupby(['LC_REF', 'Category']).apply(lambda x: ', '.join(x.vals)).reset_index()
print(car_df)

#      LC_REF Category            0
# 0  DT 17 1C       WH   Red, Fools
# 1  DT 17 1C       WM  Tesla, Merc

一些指导步骤:

  1. 翻转example字典:键到值列表和键值。这样做有助于搜索项目。您将所有与Food相关的项目放在一个列表中,将与Car相关的项目放在另一个列表中。这样,如果要检查列是否包含Food项,您只需使用pandas .isin对象的Series方法并提供{{1物品。类似地,在查找Food项时,您将遵循相同的步骤。

  2. Car起始数据帧(pd.melt)。这使得数据框形状(从宽到长)有利于后续操作。

  3. 使用布尔索引来获取df1列包含valsFood项的行。

  4. 对列Cargroup-by使用LC_REF操作,然后加入Category列中的项目。

  5. 我希望这会有所帮助。