У меня есть фрейм данных analysis_df
со следующей структурой:
... FileName UserSID ImageSize ImageChecksum
0 2197173372750839 0 17068032 11781483
1 5966634109289989 0 24576 42058
... ... ... ... ...
7500 6817023204572264 0 22000 123456
7501 6817023204572264 0 22000 123456
и нужно создать новую строку, которая сообщает, сколько раз каждый ImageChecksum
повторяется в таблице. Итак, я считаю их:
count_db = {}
for checksum in analysis_df['ImageChecksum']:
checksum = str(checksum)
if checksum in count_db:
count_db[checksum] += 1
else:
count_db[checksum] = 1
print(f"count_db: {count_db}")
выход:
count_db: {'11781483': 100, '42058': 100, '56817': 100, '491537': 100, '195631': 100, '146603': 100, '104915': 100, ... [snip] ..., '123456': 2}
Итак, в соответствии с Ответ на вопрос, связанный, но не совсем идентичный, я могу сделать что-то подобное, например:
import pandas as pd
import numpy as np
df = pd.DataFrame([['dog', 'hound', 5],
['cat', 'ragdoll', 1]],
columns=['animal', 'type', 'age'])
df['description'] = 'A ' + df.age.astype(str) + ' years old ' \
+ df.type + ' ' + df.animal
Но когда я пытаюсь применить это решение к своему делу, я получаю сообщение об ошибке:
analysis_df['ImageChecksum_Count'] = count_db[str(analysis_df['ImageChecksum'])]
---------------------------------------------------------------------------
KeyError Traceback (most recent call last)
Input In [22], in <cell line: 21>()
17 count_db[checksum] = 1
19 print(f"count_db: {count_db}")
---> 21 analysis_df['ImageChecksum_Count'] = count_db[str(analysis_df['ImageChecksum'])]
23 analysis_df.head()
KeyError: '0 11781483\n1 42058\n2 56817\n3 491537\n4 195631\n ... \n7497 125321\n7498 57364\n7499 0\n7500 123456\n7501 123456\nName: ImageChecksum, Length: 7502, dtype: int64'
Глядя на эту ошибку, я в основном понимаю, что сделал; Я пытаюсь применить обычное программирование к такого рода питоническим, векторизованным функциям, и это не работает.
Я всегда нахожу векторизованный синтаксис и программирование в Python запутанным, с перегруженными операторами и всякой магией, которая скрывается за таким синтаксисом. Это очень чуждо мне из-за фона JavaScript.
Может ли кто-нибудь объяснить правильный способ сделать это?
Редактировать:
Я обнаружил, что это работает:
for i, row in analysis_df.iterrows():
analysis_df.iat[i, checksum_count_col_index] = count_db[str(analysis_df.iat[i, checksum_col_index])]
Но не противоречит ли этот подход векторизованному подходу, который вы должны использовать с DataFrames, особенно с большими наборами данных? Я все еще был бы рад узнать, как это сделать правильно.
Чтобы создать новую строку, которая сообщает, сколько раз повторяется каждая ImageChecksum
, создайте группу с groupby('ImageChecksum')
и используйте Pandas transform
с функцией count
для создания DataFrame, содержащего общее количество групп для каждой строки в той же группе.
import pandas as pd
import numpy as np
#setup
np.random.seed(42)
d = {
'FileName': np.random.randint(1e10,1e11,(7500,)),
'UserSID': 0,
'ImageSize': np.random.randint(10e3,10e6,(7500,)),
'ImageChecksum': np.random.randint(1e3,2e3,(7500,))
}
df = pd.DataFrame(d)
#code
df['Checksum_Count'] = df.groupby('ImageChecksum')['ImageChecksum'].transform('count')
print(df)
Выход из дф
FileName UserSID ImageSize ImageChecksum Checksum_Count
0 39190929843 0 2507537 1308 5
1 56298420295 0 6210513 1435 8
2 37684640889 0 8926726 1181 10
3 87738800342 0 7546371 1587 13
4 54922131914 0 9606013 1615 3
... ... ... ... ... ...
7495 26663101742 0 2712348 1930 8
7496 69910223413 0 4020112 1284 10
7497 12097837305 0 9868594 1549 8
7498 46519177978 0 8563465 1196 9
7499 38437838102 0 5486946 1279 5
[7500 rows x 5 columns]
# Check how many times (and where) checksum value "1615" repeats
df[df['ImageChecksum'] == 1615]
FileName UserSID ImageSize ImageChecksum Checksum_Count
4 54922131914 0 9606013 1615 3
689 65788124385 0 5926645 1615 3
7401 70505133093 0 5343748 1615 3
Рад, что это сработало для вас :)
Вау,
thanks
*a million
.