在系列采摘一定的值作为标题

问题描述 投票:4回答:3

我有了一个看起来像一列数据框:

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')

清理数据时,这似乎是一个相当常见的情况是有这样做的一个标准的/更好的办法?

python pandas
3个回答
4
投票

我可以让你开始使用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

您可以使用包像pycountry(或类似的东西),以验证国名。

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功能的全部。


4
投票

使用提取物

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

0
投票

下面是使用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
© www.soinside.com 2019 - 2024. All rights reserved.