我真的不知道如何给出一个好的描述性标题,但这是我的问题。让我们考虑一个DataFrame df
:
col_name
0 Category1
1 item1()
2 item2()
3 Category2
4 item3()
5 item4()
6 item5()
我需要得到这个。
categories items
0 Category1 item1
1 Category1 item2
2 Category2 item3
3 Category2 item4
4 Category2 item5
但是... categories
可以是大陆和 items
可能是国家。我知道,所有的项目都有 ()
里面有一个表达式,所以我可以很容易地提供一个布尔掩码,然后创建一个包含 categories
与。
msk = df[~df['col_name'].str.contains('[^A-Za-z\s]')]['col_name'].tolist()
但现在,现在我被卡住了。请您给我点建议好吗?
让我们做 startswith
找到类别行,并创建另一列与 ffill
df['category']=df.col_name.mask(df.col_name.str.endwith('Category')).ffill()
#df['category']=df.col_name.mask(df.col_name.str.endswith(')')).ffill()
df=df[df.category!=df.col_name]
df
Out[241]:
col_name category
1 item1() Category1
2 item2() Category1
4 item3() Category2
5 item4() Category2
6 item5() Category2
这里需要指定如何区分非类别或类别值。在这些解决方案中,如果 (
中的数据,然后用缺失值替换这些值,并向前填充,然后替换成 ()
最后用原始掩码过滤。
m = df['col_name'].str.contains('(', regex=False)
df['categories'] = df['col_name'].mask(m).ffill()
df['items'] = df.pop('col_name').str.replace('[\(\)]', '')
df = df[m]
print (df)
categories items
1 Category1 item1
2 Category1 item2
4 Category2 item3
5 Category2 item4
6 Category2 item5
用你的掩码加上数字是解决方案改变的。
m = df['col_name'].str.contains('[^A-Za-z0-9\s]')
df['categories'] = df['col_name'].mask(m).ffill()
df['items'] = df.pop('col_name').str.replace('[\()]', '')
df = df[m]
print (df)
categories items
1 Category1 item1
2 Category1 item2
4 Category2 item3
5 Category2 item4
6 Category2 item5