【问题标题】:How do I create a new column in a dataframe from an existing column using conditions?如何使用条件从现有列在数据框中创建新列?
【发布时间】:2019-11-09 13:48:15
【问题描述】:

我有一列包含所有看起来像这样的数据(需要分隔的值有一个类似 (c) 的标记):

UK (c)
London
Wales
Liverpool
US (c)
Chicago
New York
San Francisco
Seattle
Australia (c)
Sydney
Perth

我希望它分成两列,如下所示:

London          UK
Wales           UK
Liverpool       UK
Chicago         US
New York        US
San Francisco   US
Seattle         US
Sydney          Australia
Perth           Australia

问题 2:如果国家没有像 (c) 这样的模式怎么办?

【问题讨论】:

  • 这是一个有点有趣的字符串操作问题,按照这个标签的通常标准,这是一个相对不错的问题,包含样本数据和明确指定的预期输出。我不是在抱怨¯\_(ツ)_/¯

标签: python pandas dataframe series


【解决方案1】:

逐步使用endswithffill + str.strip

df['country']=df.loc[df.city.str.endswith('(c)'),'city']
df.country=df.country.ffill()
df=df[df.city.ne(df.country)]
df.country=df.country.str.strip('(c)')

【讨论】:

  • 如果国家没有像 (c) 这样的模式怎么办?
  • @Tsatsa 在这种情况下你可能需要建立一个国家列表,并使用isin
【解决方案2】:

extractffill

extractffill 开始,然后删除冗余行。

df['country'] = (
    df['data'].str.extract(r'(.*)\s+\(c\)', expand=False).ffill())
df[~df['data'].str.contains('(c)', regex=False)].reset_index(drop=True)

            data    country
0         London         UK
1          Wales         UK
2      Liverpool         UK
3        Chicago         US
4       New York         US
5  San Francisco         US
6        Seattle         US
7         Sydney  Australia
8          Perth  Australia

在哪里,

df['data'].str.extract(r'(.*)\s+\(c\)', expand=False).ffill()

0            UK
1            UK
2            UK
3            UK
4            US
5            US
6            US
7            US
8            US
9     Australia
10    Australia
11    Australia
Name: country, dtype: object

模式'(.*)\s+\(c\)' 匹配“国家(c)”形式的字符串并提取国家名称。不匹配此模式的任何内容都将替换为 NaN,因此您可以方便地向前填充行。


splitnp.whereffill

这在“(c)”上分裂。

u = df['data'].str.split(r'\s+\(c\)')
df['country'] = pd.Series(np.where(u.str.len() == 2, u.str[0], np.nan)).ffill()

df[~df['data'].str.contains('(c)', regex=False)].reset_index(drop=True)

            data    country
0         London         UK
1          Wales         UK
2      Liverpool         UK
3        Chicago         US
4       New York         US
5  San Francisco         US
6        Seattle         US
7         Sydney  Australia
8          Perth  Australia

【讨论】:

  • extract('(.*)\s+\(c\)') 将您从.str.strip() 中拯救出来。
【解决方案3】:

您可以先使用str.extract 定位以(c) 结尾的城市并提取国家名称,然后使用ffill 填充新的country 列。

相同的提取匹配可用于定位要删除的行,即notna的行:

m = df.city.str.extract('^(.*?)(?=\(c\)$)')
ix = m[m.squeeze().notna()].index
df['country'] = m.ffill()
df.drop(ix)

            city     country
1          London         UK 
2           Wales         UK 
3       Liverpool         UK 
5         Chicago         US 
6        New York         US 
7   San Francisco         US 
8         Seattle         US 
10         Sydney  Australia 
11          Perth  Australia 

【讨论】:

    【解决方案4】:

    您也可以将np.wherestr.contains 一起使用:

    mask = df['places'].str.contains('(c)', regex = False)
    df['country'] = np.where(mask, df['places'], np.nan)
    df['country'] = df['country'].str.replace('\(c\)', '').ffill()
    df = df[~mask]
    df
                places     country
    1          London         UK 
    2           Wales         UK 
    3       Liverpool         UK 
    5         Chicago         US 
    6        New York         US 
    7   San Francisco         US 
    8         Seattle         US 
    10         Sydney  Australia 
    11          Perth  Australia 
    

    str contains 查找(c),如果存在,将为该索引返回True。如果此条件为 True,则国家/地区值将添加到国家/地区列中

    【讨论】:

      【解决方案5】:

      您可以执行以下操作:

      data = ['UK (c)','London','Wales','Liverpool','US (c)','Chicago','New York','San Francisco','Seattle','Australia (c)','Sydney','Perth']
      df = pd.DataFrame(data, columns = ['city'])
      df['country'] = df.city.apply(lambda x : x.replace('(c)','') if '(c)' in x else None)
      df.fillna(method='ffill', inplace=True)
      df = df[df['city'].str.contains('\(c\)')==False]
      

      输出

      +-----+----------------+-----------+
      |     |     city       |  country  |
      +-----+----------------+-----------+
      |  1  | London         | UK        |
      |  2  | Wales          | UK        |
      |  3  | Liverpool      | UK        |
      |  5  | Chicago        | US        |
      |  6  | New York       | US        |
      |  7  | San Francisco  | US        |
      |  8  | Seattle        | US        |
      | 10  | Sydney         | Australia |
      | 11  | Perth          | Australia |
      +-----+----------------+-----------+
      

      【讨论】:

        猜你喜欢
        • 2020-09-18
        • 1970-01-01
        • 2021-02-08
        • 1970-01-01
        • 2018-07-10
        • 2021-06-10
        • 2022-01-18
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多