【问题标题】:More pythonic way to edit column values - python pandas更多pythonic方式来编辑列值 - python pandas
【发布时间】:2020-10-19 03:25:08
【问题描述】:

我觉得必须有一种更 Pythonic 的方式(即:更简单、更直接)来更改我正在使用的数据框中的列值。基本上,我正在尝试根据“ID”列的值编辑列 match 的值。

举个例子:

data = [['tom', 10, 111], ['nick', 15, 112], ['juli', 14, 113], ['mary', 17, 114]] 

# Create the pandas DataFrame 
df = pd.DataFrame(data, columns = ['Name', 'Age', 'ID']) 

我有一个简单的数据框,df

现在我将数据框分成几片

df2 = df.loc[df['ID'] == 111]
df3 = df.loc[df['ID'] == 112]
df4 = df.loc[df['ID'] == 113]
df5 = df.loc[df['ID'] == 114]

我想做的是在我的原始数据框中创建一个新列(称为“匹配”)。然后我想根据 ID 列将df2,df3,df4,df5 与它进行比较。在“匹配”列中,我将记录这些匹配发生的时间。让我逐步完成我的过程。

如果我这样做......

df['match_checker'] = df2['ID'].isin(df['ID'])
df.loc[df['match_checker'] == True, 'match'] = 'Round 1'

df['match_checker'] = df3['ID'].isin(df['ID'])
df.loc[df['match_checker'] == True, 'match'] = 'Round 2'

df['match_checker'] = df4['ID'].isin(df['ID'])
df.loc[df['match_checker'] == True, 'match'] = 'Round 3'

df['match_checker'] = df5['ID'].isin(df['ID'])
df.loc[df['match_checker'] == True, 'match'] = 'Round 4'

生成的数据框如下所示。这是期望的结果。 (match_checker 列会随着每次迭代而改变)。

   Name  Age   ID match_checker    match
0   tom   10  111           NaN  Round 1
1  nick   15  112           NaN  Round 2
2  juli   14  113           NaN  Round 3
3  mary   17  114          True  Round 4

我有想要的结果,但是创建数据帧的一个子集,然后将其与原始数据帧进行比较似乎是一种不好的方法。

注意 我不是在寻找以下解决方案:

df.loc[df['ID'] == 111), 'match'] = 'Round 1'

【问题讨论】:

标签: python pandas dataframe


【解决方案1】:

这个怎么样:

rounds = {
    111: 'Round 1',
    112: 'Round 2',
    113: 'Round 3',
    114: 'Round 4',
}

df['match'] = [rounds[i] for i in df.ID]


   Name  Age   ID    match
0   tom   10  111  Round 1
1  nick   15  112  Round 2
2  juli   14  113  Round 3
3  mary   17  114  Round 4

【讨论】:

    【解决方案2】:

    我认为您只想让“match”和“match_checker”一一更新。所以我为你做了这个。

    import numpy as np
    import pandas as pd
    
    
    class ColumnUpdater(object):
        def __init__(self, to_update_df, prefix="Record"):
            self.to_update_df = to_update_df
            self.prefix = prefix
            self.current_index = 0
            self.match_checker = None
    
        def update_func(self, util_id):
            if isinstance(util_id, pd.DataFrame):
                return
            util_id = util_id.iloc[0]
            self.to_update_df.loc[:, "match_checker"] = self.to_update_df["ID"] == util_id
            current_match = f"{self.prefix} {self.current_index}"
            self.current_index += 1
            return current_match
    
        def process(self):
            self.to_update_df.loc[:, "match_checker"] = np.nan
            self.to_update_df.loc[:, "util_id"] = self.to_update_df["ID"]
            self.to_update_df.loc[:, "match"] = self.to_update_df.groupby("ID")[
                "util_id"
            ].transform(self.update_func)
            return self.to_update_df.drop(columns="util_id")
    
    
    if __name__ == "__main__":
        data = np.repeat(
            [["tom", 10, 111], ["nick", 15, 112], ["juli", 14, 113], ["mary", 17, 114]],
            5,
            axis=0,
        )
        # Create the pandas DataFrame
        df = pd.DataFrame(data, columns=["Name", "Age", "ID"])
        result = ColumnUpdater(df).process()
        print(result)
    

    【讨论】:

      猜你喜欢
      • 2016-02-09
      • 1970-01-01
      • 1970-01-01
      • 2017-05-20
      • 1970-01-01
      • 2021-06-21
      • 2020-06-27
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多