#python #pandas #dataframe #pandas-groupby
Вопрос:
У меня df
есть список личности, происхождения и места назначения
df = pd.DataFrame({'PersonID':['1','1','2','2','2','3'],'O':['A','B','C','B','A','X'],'D':['B','A','B','A','B','Y']})
в df:
PersonID O D
1 A B
1 B A
2 C B
2 B A
2 A B
3 X Y
Я сгруппировал их по df df_grouped = df.groupby(['O','D'])
и сопоставил их с другим фреймом данных, taxi
.
TaxiID O D
T1 B A
T2 A B
T3 C B
точно так же я группируюсь по taxi
своим O
и D
. Затем я объединил их после объединения и подсчета идентификаторов персон и таксидов на пару O-D. Я сделал это, чтобы посмотреть, сколько такси доступно для скольких людей.
O D PersonID TaxiID
count count
A B 2 1
B A 2 1
C B 1 1
Теперь я хочу выполнить df.loc
, чтобы взять только те идентификаторы персон, которые были учтены в объединенном файле. Как я могу это сделать? Я пытался нам:
seek = df.loc[df.PersonID.isin(merged['PersonID'])]
но он возвращает пустой фрейм данных. Что я могу сделать для этого?
редактировать: я прилагаю полный код для этого случая, используя фиктивные данные
df = pd.DataFrame({'PersonID':['1','1','2','2','2','3'],'O':['A','B','C','B','A','X'],'D':['B','A','B','A','B','Y']})
taxi = pd.DataFrame({'TaxiID':['T1','T2','T3'],'O':['B','A','C'],'D':['A','B','B']})
df_grouped = df.groupby(['O','D'])
taxi_grouped = taxi.groupby(['O','D'])
dfm = df_grouped.agg({'PersonID':['count',list]}).reset_index()
tgm = taxi_grouped.agg({'TaxiID':['count',list]}).reset_index()
merged = pd.merge(dfm, tgm, how='inner')
seek = df.loc[df.PersonID.isin(merged['PersonID'])]
Комментарии:
1. Можете ли вы показать свой полный код?
2. @jezrael Я отредактировал его и добавил полный код
Ответ №1:
Выберите MultiIndex
tuple
с Series.explode
помощью для скаляров из вложенных списков:
seek = df.loc[df.PersonID.isin(merged[('PersonID', 'list')].explode().unique())]
print (seek)
PersonID O D
0 1 A B
1 1 B A
2 2 C B
3 2 B A
4 2 A B
Для повышения производительности возможно использование set comprehension
с выравниванием:
seek = df.loc[df.PersonID.isin(set(z for x in merged[('PersonID', 'list')] for z in x))]
print (seek)
PersonID O D
0 1 A B
1 1 B A
2 2 C B
3 2 B A
4 2 A B
Комментарии:
1. Я ожидаю, что его будет быстрее использовать
merged[('PersonID', 'list')].explode().unique()
для больших кадров данных.2. @mozway — я, согласен.
3. @mozway @jezrael это прекрасно работает, спасибо! таким образом, в основном то, что он сделал, состояло в преобразовании
merged['PersonID']
в список, а затем вdf.loc
получении данных из df с этим списком в качестве ссылки. Верна ли моя интерпретация?4. @Ricky Вы близки, это массив numpy, подобный списку для первого решения, для второго он задан для справки.