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

时间:2019-02-04 17:32:56

标签: python pandas

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

OTSession

我想从此列表中提取国家/地区名称,然后将其变成另一列,如下所示:

Japan
valA
valB
Ghana
valC
valD
...

我肯定已经在SO上找到了答案,但是我一直没有找到正确的关键字来提出它。

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

Japan    valA
Japan    valB
Ghana    valC
Ghana    valD

在清理数据时,这似乎是一个相当普遍的用例,是否有标准/更好的方法?

3 个答案:

答案 0 :(得分: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函数。

答案 1 :(得分: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

答案 2 :(得分: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