【问题标题】:How to create a new column in pandas and set its values according to whether a second column includes a string from various lists of strings如何在 pandas 中创建一个新列并根据第二列是否包含来自各种字符串列表的字符串来设置其值
【发布时间】:2020-11-18 00:04:05
【问题描述】:

我有一个包含土耳其省份值的数据框:

df['province']
2078982        Adana
2078983        Adana
2078984        Adana
2078985        Adana
2078986        Adana
   
2210113    Zonguldak
2210114    Zonguldak
2210115    Zonguldak
2210116    Zonguldak
2210117    Zonguldak

我想编写一个 if 循环或一个函数来创建一个新列,该列将按地区对每个省份进行分类。因此,我创建了 7 个列表,其中包含 7 个区域中每个区域所包含的省份:

aegean = ['Izmir', 'Aydin', 'Manisa', 'Uşak', 'Afyonkarahisar', 'Denizli', 'Kütahya', 'Muğla']
blacksea = ['Amasya', 'Gümüşhane', 'Bartın', 'Bolu', 'Giresun', 'Kastamonu', 'Karabük','Ordu', 'Rize', 'Samsun',
            'Sinop', 'Tokat', 'Trabzon', 'Zonguldak', 'Artvin', 'Bayburt', 'Çorum', 'Düzce']
cen_ana= ['Aksaray', 'Kırıkkale', 'Kırşehir', 'Nevşehir', 'Ankara', 'Çankırı', 'Eskisehir', 'Karaman', 'Kayseri', 'Konya', 'Sivas', 'Yozgat']
eas_ana= ['Ağrı', 'Bingöl', 'Elazığ', 'Hakkari', 'Iğdır', 'Kars', 'Tunceli', 'Van', 'Ardahan', 'Erzurum','Şırnak']
marmara=['Edirne', 'Istanbul', 'Kırklareli', 'Kocaeli', 'Tekirdağ', 'Yalova', 'Balıkesir', 'Bilecik', ' Bursa','Çanakkale','Sakarya' ]
medite=['Adana', 'Antalya', 'Mersin', 'Burdur', 'Hatay', 'Isparta', 'Osmaniye','Kahramanmaraş' ]
sou_ana=['Adiyaman', 'Batman','Diyarbakır', 'Gaziantep', 'Siirt', 'Mardin',  'Şanlıurfa']

完成后,我使用 for 和 if 循环遍历数据集:


for i, row in df.iterrows():
    df['Region']='something'
    if any(e in df["province"] for e in aegean):
        df['Region']=="Aegean Region"
    elif any(q in df["province"] for q in blacksea):
        df['Region']=="Black Sea Region"
    elif any(s in df["province"] for s in cen_ana):
        df['Region']=="Central Anatolia"
    elif any(c in df["province"] for c in eas_ana):
        df['Region']=="Eastern Anatolia"
    elif any(v in df["province"] for v in sou_ana):
        df['Region']=="Southern Anatolia"
    elif any(g in df["province"] for g in marmara):
       df['Region']=="Marmara"
    elif any(h in df["province"] for h in medite):
        df['Region']=="Mediterranean"
    else:
        df['Region']=="Other"

但由于某种原因,我最终得到的只是我的所有列的值“某物”。


df['Region']
Out[148]: 
2078982    something
2078983    something
2078984    something
2078985    something
2078986    something
   
2210113    something
2210114    something
2210115    something
2210116    something
2210117    something
Name: Region, Length: 15901, dtype: object

我尝试了一些建议使用函数的示例:

def regionaler(x):
    if any(e in df["province"] for e in aegean):
        return "Aegean Region"
    elif any(e in df["province"] for e in blacksea):
        return "Black Sea Region"
    elif any(e in df["province"] for e in cen_ana):
        return "Central Anatolia"
    elif any(e in df["province"] for e in eas_ana):
        return "Eastern Anatolia"
    elif any(e in df["province"] for e in sou_ana):
        return "Southern Anatolia"
    elif any(e in df["province"] for e in marmara):
        return "Marmara"
    elif any(e in df["province"] for e in medite):
        return "Mediterranean"
    else:
        return "Other"

但结果对我来说同样不正确:



df['Region'] = df.apply(regionaler,axis=1)
df['Region']
Out[151]: 
2078982    Other
2078983    Other
2078984    Other
2078985    Other
2078986    Other
 
2210113    Other
2210114    Other
2210115    Other
2210116    Other
2210117    Other
Name: Region, Length: 15901, dtype: object

我有一种感觉,我正在犯一些非常愚蠢的错误,这些错误可以很容易地修复但无法解决。非常感谢任何可以提供帮助的人!

【问题讨论】:

    标签: python python-3.x pandas string dataframe


    【解决方案1】:

    您可以使用Series.map 做得更好:

    使用如下区域列表创建dict(我仅使用示例):

    In [2511]: medite=['Adana', 'Antalya', 'Mersin']
    In [2508]: blacksea = ['Amasya', 'Gümüşhane', 'Bartın','Zonguldak']
    
    In [2512]: province_map = {'medite': medite, 'blacksea':blacksea}
    
    In [2513]: print(province_map)
    Out[2513]: 
    {'medite': ['Adana', 'Antalya', 'Mersin'],
     'blacksea': ['Amasya', 'Gümüşhane', 'Bartın', 'Zonguldak']}
    

    现在,将 province_map 值转换为键,如下所示:

    In [2514]: d = {i: k for k,v in province_map.items() for i in v}
    
    In [2515]: print(d)
    Out[2515]: 
    {'Adana': 'medite',
     'Antalya': 'medite',
     'Mersin': 'medite',
     'Amasya': 'blacksea',
     'Gümüşhane': 'blacksea',
     'Bartın': 'blacksea',
     'Zonguldak': 'blacksea'}
    

    现在使用Series.map 在数据框中创建新列:

    In [2518]: df['Region'] = df.province.map(d)
    
    In [2519]: df
    Out[2519]: 
              province    Region
    2078982      Adana    medite
    2078983      Adana    medite
    2078984      Adana    medite
    2078985      Adana    medite
    2078986      Adana    medite
    2210113  Zonguldak  blacksea
    2210114  Zonguldak  blacksea
    2210115  Zonguldak  blacksea
    2210116  Zonguldak  blacksea
    2210117  Zonguldak  blacksea
    

    【讨论】:

    • 非常感谢您的回复。这很有意义!
    【解决方案2】:

    @Mayank 的解决方案是在 pandas 中实现映射的更好方法。您的解决方案不起作用的原因是, 在第一种方法中,您在迭代时修改了一行。这不会有任何影响。 请参考 Pandas 文档,https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.iterrows.html

    在第二种方法中,您正在遍历该行,而是尝试检查 df["province"]。请将其更改为 x。

    if any(e in x["province"] for e in aegean):
            return "Aegean Region"
    

    【讨论】:

    • 非常感谢 sowmyaiyer 的回复。这真的有助于我理解我的错误并在将来避免它!
    【解决方案3】:

    我能够通过使用 lambda x 函数以及 if 和 else 参数来解决我的问题:

    
         
    df['Region'] = df.province.apply(lambda x: "Aegean Region" if x in aegean else ("Black Sea Region" if x in blacksea 
                                                                                                            else ("Central Anatolia" if x in cen_ana 
                                                                                                                  else ("Eastern Anatolia" if x in eas_ana 
                                                                                                                        else ("Southern Anatolia" if x in sou_ana 
                                                                                                                              else ("Marmara" if x in marmara 
                                                                                                                                    else ("Mediterranean" if x in medite                                                                                                                    
                                                                                                                                          else "Other")))))))
    

    我很想知道为什么这会奏效,但上面的脚本却没有。如果有人能告诉我更多,你会非常友善!

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-09-12
      • 2023-01-03
      • 1970-01-01
      • 2017-07-02
      • 2021-11-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多