У меня есть кадр данных, в котором я хотел бы определить, сколько уникальных видов птиц каждый человек видел, кто участвовал в моем "Большом году".
Я попытался использовать понимание списка и цикл для итерации по каждой строке и определить, уникален ли он с помощью.is_unique(), но это, по-видимому, является источником большей части моего бедствия. Я могу получить список всех уникальных видов с.unique(), довольно красиво, но я хотел бы как-то получить людей, связанных с этими птицами.
df = pd.DataFrame({'Species':['woodpecker', 'woodpecker', 'dove', 'mockingbird'], 'Birder':['Steve', 'Ben','Ben','Greg']})
ben_unique_bird = [x for x in range(len(df['Species'])) if df['Birder'][x]=='Ben' and df['Species'][x].is_unique()]
Редактировать: Я думаю, что я неясен в this-. Я хочу получить список птиц, которые каждый человек видел, что никто другой не сделал. Таким образом, выход будет чем-то вроде (Steve, 0), (Ben, 1), (Greg, 1), в любом формате.
Спасибо!
Вы можете создать вспомогательную серию через pd.DataFrame.duplicated
а затем использовать GroupBy
+ sum
:
counts = data.assign(dup_flag=df['Species'].duplicated(keep=False))\
.groupby('Birder')['dup_flag'].sum().astype(int)
for name, count in counts.items():
print(f'{name} saw {count} bird(s) that no one else saw')
Результат:
Ben saw 1 bird(s) that no one else saw
Greg saw 0 bird(s) that no one else saw
Steve saw 1 bird(s) that no one else saw
Это можно сделать с пониманием списка довольно легко.
df = pd.DataFrame({'Species':['woodpecker', 'woodpecker', 'dove', 'mockingbird'], 'Birder':['Steve', 'Ben','Ben','Greg']})
matches = [(row[1], row[2]) for row in df.itertuples() if (row[1],row[2]) not in matches]
Это дает список кортежей в качестве вывода:
[('Steve', 'woodpecker'), ('Ben', 'woodpecker'), ('Ben', 'dove'), ('Greg', 'mockingbird')]
название уникальных птиц, которые они видели
ben_unique_bird = df[df['Birder'] == 'Ben']['Species'].unique()
количество уникальных птиц, которые они видели
len(df[df['Birder'] == 'Ben']['Species'].unique())
Рекомендуемый метод 1 для получения таблицы
df.groupby(['Birder']).agg({"Species": lambda x: x.nunique()})
тот же самый метод разбит
for i in df['Birder'].unique():
print (" Name ",i," Distinct count ",len(df[df['Birder'] == i]['Species'].unique())," distinct bird names ",df[df['Birder'] == i]['Species'].unique())
Я понял ужасный способ делать то, что хочу, но он работает. Пожалуйста, дайте мне знать, если у вас есть более эффективный способ сделать это, потому что я знаю, что должен быть один.
data = pd.DataFrame({'Species':['woodpecker', 'woodpecker', 'dove', 'mockingbird'], 'Birder':['Steve', 'Ben','Ben','Greg']})
ben_birds = []
steve_birds = []
greg_birds = []
#get all the names of the birds that people saw and put them in a list
for index, row in data.iterrows():
if row['Birder'] == 'Bright':
ben_birds.append(row['Species'])
elif row['Birder'] == 'Filios':
steve_birds.append(row['Species'])
else:
greg_birds.append(row['Species'])
duplicates=[]
#compare each of the lists to look for duplicates, and make a new list with those
for bird in ben_birds:
if (bird in steve_birds) or (bird in greg_birds):
duplicates.append(bird)
for bird in steve_birds:
if (bird in greg_birds):
duplicates.append(bird)
#if any of the duplicates are in a list, remove those birds
for bird in ben_birds:
if bird in duplicates:
ben_birds.remove(bird)
for bird in steve_birds:
if bird in duplicates:
steve_birds.remove(bird)
for bird in greg_birds:
if bird in duplicates:
greg_birds.remove(bird)
print(f'Ben saw {len(ben_birds)} Birds that no one else saw')
print(f'Steve saw {len(steve_birds)} Birds that no one else saw')
print(f'Greg saw {len(greg_birds)} Birds that no one else saw')