我有一个DataFrame,其列如下所示:
OTSession
我想从此列表中提取国家/地区名称,然后将其变成另一列,如下所示:
Japan
valA
valB
Ghana
valC
valD
...
我肯定已经在SO上找到了答案,但是我一直没有找到正确的关键字来提出它。
现在,我正在执行以下操作,但随后必须删除最初包含国家名称的行:
Japan valA
Japan valB
Ghana valC
Ghana valD
在清理数据时,这似乎是一个相当普遍的用例,是否有标准/更好的方法?
答案 0 :(得分:4)
我可以帮助您开始使用map
和ffill
。
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