Недавно мне помогли ответить на вопрос https://stackoverflow.com/a/65417494/14872543, но мне не хватает знаний модифицировать функцию для решения той же задачи получения количества обратных рейсов в фрейм данных, если появляются дополнительные строковые столбцы.
station from station to lgot count
0 20001 20040 stud 22
1 20001 20040 fed 33
0 20040 20001 stud 44
2 20040 20001 reg 55
3 20002 20015 stud 66
3 20015 20002 stud 77
station from station to lgot count count_back
0 20001 20040 stud 22 44
1 20001 20040 fed 33 0
2 20040 20001 reg 55 0
3 20002 20015 stud 66 77
Мое решение: заменить lgot на int lgot id (не так много типов lgot ~ 7), объединить столбцы «станция от» и «станция до», используя функцию, предложенную в решении. Выполните обратное преобразование полученного кадра данных. Может быть, это от непонимания того, как работает функция
df.head()
station from station to lgot count
0 2030080 2030000 full 464
1 2030000 2030080 full 395
2 2030150 2030000 full 330
3 2030000 2030150 full 285
4 2030240 2030000 full 249
df.loc[df['lgot'] == 'full', 'lgot'] = '11'
df.loc[df['lgot'] == 'rzd', 'lgot'] = '22'
df.loc[df['lgot'] == 'fed', 'lgot'] = '33'
df.loc[df['lgot'] == 'reg', 'lgot'] = '44'
df.loc[df['lgot'] == 'stud', 'lgot'] = '55'
df.loc[df['lgot'] == 'voen', 'lgot'] = '66'
df['station to'] = df['station to'].astype('string')+df['lgot']
df['station from'] = df['station from'].astype('string')+df['lgot']
df['station to'] = df['station to'].astype('int')
df['station from'] = df['station from'].astype('int')
df.drop(['lgot'], axis='columns', inplace=True)
def roundtrip(df):
a, b, c, d = 'station from', 'station to', 'count', 'count_back'
idx = df[a] > df[b]
df = df.assign(**{d: 0})
df.loc[idx, [a, b, c, d]] = df.loc[idx, [b, a, d, c]].values
return df.groupby([a, b]).sum()
df = roundtrip(df)
df= df.reset_index()
df['lgot'] = df["station from"].astype('string').str.slice(start=-2)
df['station from'] = df['station from'].astype('string').str.slice(stop=7)
df['station to'] = df['station to'].astype('string').str.slice(stop=7)
df.head()
station from station to count count_back lgot
0 1003704 2030133 0 1 11
1 1003704 2030160 0 1 11
2 1003704 2031321 0 1 11
3 1003704 2030132 0 1 22
4 1003704 2030133 0 1 22
ОК добавил, но выглядит отвратительно, как будто я работаю в экселе :)
Решение Пьера больше не работает из другого вопроса; потому что с новыми данными df[a] > df[b]
терпит неудачу, поскольку пятая строка теперь меньше четвертой строки. Таким образом, лучший способ сделать это с новыми данными — использовать .shift()
. Кроме того, вы можете передать sort=False
своей группе, чтобы улучшить производительность и поддерживать порядок. Наконец, я использовал .reset_index()
и изменил переменные столбца для a,b,c,d,e
в соответствии с новыми данными.
def roundtrip(df):
a, b, c, d, e = 'station from', 'station to', 'lgot', 'count', 'count_back'
idx = (df[a] == df[b].shift()) & (df[b] == df[a].shift())
df = df.assign(**{e: 0})
df.loc[idx, [a, b, c, d, e]] = df.loc[idx, [b, a, c, e, d]].values
return df.groupby([a, b, c], sort=False).sum().reset_index()
roundtrip(df)
Out[1]:
station from station to lgot count count_back
0 20001 20040 stud 22 44
1 20001 20040 fed 33 0
2 20040 20001 reg 55 0
3 20002 20015 stud 66 77
Я постараюсь понять код. Я попробовал эту функцию в своем наборе данных, и первые две строки были подсчитаны правильно, а затем произошел сбой. station from station to lgot count count_back 0 2030080 2030000 full 464 395 1 2030150 2030000 full 330 285 2 2030240 2030000 full 249 0 3 2030080 2030122 reg 225 0 4 2030000 2030240 full 211 0
@СергейШамсуаров СергейШамсуаров решение, которое я предоставил, работает с данными образца, которые вы предоставили. Новые данные в комментарии выглядят совсем по другому шаблону. Пожалуйста, примите решение и создайте еще один вопрос. Не забудьте указать правильные данные в своем вопросе, если хотите получить правильный ответ. Спасибо!
Спасибо, я новичок в python и первый день использую stackoverflow. Нормально ли создавать аналогичный запрос с приложением с расширенной датой и дополнительным комментарием?
Вы должны по крайней мере показать работу, которую вы сделали, прежде чем просто просить решения.