У меня есть dataframe следующим образом:
df = pd.DataFrame({
'Event':['2018 Green Meeting','2018 Yellow Meeting','2018 Red Meeting',
'2017 Green Meeting','2017 Yellow Meeting','2017 Red Meeting',
'2016 Green Meeting','2016 Yellow Meeting','2016 Red Meeting',
'Blue Meeting','Purple Meeting','Green Meeting'],
'Count':[1,2,3,4,5,6,7,8,9,10,11,12]
})
Я хочу разбить столбец событий на два столбца "Год" и "Событие_Name", чтобы получить следующий результат:
df2 = pd.DataFrame({
'Year':['2018','2018','2018',
'2017','2017','2017',
'2016','2016','2016',
'Blue Meeting','Purple Meeting','Green Meeting'],
'Event_Name':['Green Meeting','Yellow Meeting','Red Meeting',
'Green Meeting','Yellow Meeting','Red Meeting',
'Green Meeting','Yellow Meeting','Red Meeting',
'Blue Meeting','Purple Meeting','Green Meeting'],
'Count':[1,2,3,4,5,6,7,8,9,10,11,12]
})
Когда я пытаюсь использовать regex для этого. Кажется, он не работает. Я получаю два столбца "Год" и "Событие_Name". Но год пуст.
Это то, что я использую:
df[['Year','Event_Name']] = df['Event'].str.split(r'\d{4}',expand=True)
Как я могу заставить это работать правильно?
Использование str.extract
с fillna
df['Year']=df.Event.str.extract('(\d+)').fillna(df.Event)
то мы replace
df['even_name']=df.Event.str.replace('\d+', '')
df['even_name']=df.Event.str.replace('\d+', '')
@AlhpaDelta также обновляется в моем ответе.
pandas.Series.str.findall
s = df.Event.str.findall('(\d+|\D+)')
pd.DataFrame(dict(
Count=df.Count,
Event_Name=s.str[-1],
Year=s.str[0]
))
Count Event_Name Year
0 1 Green Meeting 2018
1 2 Yellow Meeting 2018
2 3 Red Meeting 2018
3 4 Green Meeting 2017
4 5 Yellow Meeting 2017
5 6 Red Meeting 2017
6 7 Green Meeting 2016
7 8 Yellow Meeting 2016
8 9 Red Meeting 2016
9 10 Blue Meeting Blue Meeting
10 11 Purple Meeting Purple Meeting
11 12 Green Meeting Green Meeting
def f(x):
a, b = x.split(None, 1)
if a.isdecimal():
return a, b
else:
return (x,)
s = df.Event.apply(f)
pd.DataFrame(dict(
Count=df.Count,
Event_Name=s.str[-1],
Year=s.str[0]
))
Count Event_Name Year
0 1 Green Meeting 2018
1 2 Yellow Meeting 2018
2 3 Red Meeting 2018
3 4 Green Meeting 2017
4 5 Yellow Meeting 2017
5 6 Red Meeting 2017
6 7 Green Meeting 2016
7 8 Yellow Meeting 2016
8 9 Red Meeting 2016
9 10 Blue Meeting Blue Meeting
10 11 Purple Meeting Purple Meeting
11 12 Green Meeting Green Meeting
Использовать extractall
:
df[['Year','Event']] = df.Event.str.extractall('(\d{4})? ?(.+$)').reset_index('match', drop=True)
Выход:
Event Count Year
0 Green Meeting 1 2018
1 Yellow Meeting 2 2018
2 Red Meeting 3 2018
3 Green Meeting 4 2017
4 Yellow Meeting 5 2017
5 Red Meeting 6 2017
6 Green Meeting 7 2016
7 Yellow Meeting 8 2016
8 Red Meeting 9 2016
9 Blue Meeting 10 NaN
10 Purple Meeting 11 NaN
11 Green Meeting 12 NaN
Это должно сделать работу
def get_year(x):
try:
return int(x.split()[0])
except:
return None
def get_event_name(x):
try:
year = int(x.split()[0])
return ' '.join(x.split()[1: ])
except:
return x
df['Year'] = df['Event'].apply(lambda x: get_year(x))
df['Event_Name'] = df['Event'].apply(lambda x: get_event_name(x))
df = df.drop(['Event', ], axis=1)
'one and two and three'.split('and')
возвращает['one ',' two ',' three']
; 'и' удаляется из результата.