Как я могу создать новый столбец DataFrame на основе объединения признака из каждой строки и его отношения к отдельному словарю?

У меня есть фрейм данных 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, особенно с большими наборами данных? Я все еще был бы рад узнать, как это сделать правильно.

Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
1
0
40
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Чтобы создать новую строку, которая сообщает, сколько раз повторяется каждая 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.

J.Todd 23.03.2022 01:46

Рад, что это сработало для вас :)

n1colas.m 23.03.2022 02:07

Другие вопросы по теме