在系列中选取某些值作为标题

2024-09-28 21:36:43 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个DataFrame,它有一个列,如下所示:

Japan
valA
valB
Ghana
valC
valD
...

我想从这个列表中提取国家名称,并将它们转换成另一个列,如下所示:

Japan    valA
Japan    valB
Ghana    valC
Ghana    valD

我确信这个问题已经有答案了,但是我还没有找到正确的关键字来显示它

现在,我正在执行以下操作,但随后必须删除最初包含国家/地区名称的行:

def get_country(row):
    if #decide if it's a country name:
        return row[0]
df['country'] = df.apply(get_country, axis=1).fillna(method='ffill')

在清理数据时,这似乎是一个相当常见的用例,有没有标准的/更好的方法


Tags: 名称dataframedf列表getif国家country
3条回答

使用提取物

new_df = df['col'].str.extract('(val.*)?(.*)').replace('', np.nan).rename(columns = {1:'Country', 0:'Value'})
new_df['Country'] = new_df['Country'].ffill()
new_df.dropna(inplace = True)


    Value   Country
1   valA    Japan
2   valB    Japan
4   valC    Ghana
5   valD    Ghana

我可以让你开始使用mapffill

def is_country(x): 
    # TODO - fill in the logic for this stub.
    return x in {'Japan', 'Ghana'}

df

       A
0  Japan
1   valA
2   valB
3  Ghana
4   valC
5   valD


df.assign(B=df['A'].where(df['A'].map(is_country)).ffill()).query('A != B')

      A      B
1  valA  Japan
2  valB  Japan
4  valC  Ghana
5  valD  Ghana

您可以使用^{}(或类似的东西)这样的包来验证国家名称

import pycountry
countries = {x.name for x in pycountry.countries}  # Initialise a set.

def is_country(x): 
    return x in countries

不过,通过这个定义,您可以将代码简化为

df.assign(B=df['A'].where(df['A'].isin(countries)).ffill()).query('A != B')

完全摆脱is_country功能

这里有一种使用groupby+pd.concat的方法。您可以显式定义countries,也可以使用您喜爱的源代码

df = pd.DataFrame({'col': ['Japan', 'valA', 'valB', 'Ghana', 'valC', 'valD']})
countries = ['Japan', 'Ghana']

grouper = df['col'].groupby(df['col'].isin(countries).cumsum())    
dfs = (pd.DataFrame({'Country': df_ctry.iat[0], 'Value': df_ctry.iloc[1:]}) \
       for _, df_ctry in grouper)

res = pd.concat(dfs, ignore_index=True)

print(res)

  Country Value
0   Japan  valA
1   Japan  valB
2   Ghana  valC
3   Ghana  valD

相关问题 更多 >