Преобразовать фрейм данных в словарь с несколькими ключами (member_IDs) и аддитивными значениями (остатки на счетах) - PullRequest
0 голосов
/ 19 марта 2020

У меня следующая проблема: Моя цель - извлечь уникальные идентификаторы элементов фрейма данных и использовать ключи as, а также извлечь и суммировать транзакции, которые они имеют, и иметь их в качестве значений.

уникальный mem_id = например, 70850441974905670928446

сумма = 150,78

card_members = df ['unique_mem_id']. unique ()

РЕДАКТИРОВАТЬ: Вот выдержка из кадра данных:

transaction_date    unique_mem_id   description amount
6/21/2014   7.08504E+22 HILLERS MARKET         NORTHVILLE   MI  61.72
6/22/2014   7.08504E+22 BUSCH'S #1032          PLYMOUTH     MI  25.48
6/23/2014   7.08504E+22 SPEEDWAY XXXXX 5 M     PLYMOUTH     MI  30.73
6/23/2014   7.08504E+22 HENDERSON GLASS INC    NOVI         MI  29.95
6/23/2014   7.08504E+22 HILLERS MARKET         NORTHVILLE   MI  59.6
6/23/2014   7.08504E+22 SPEEDWAY XXXXX 5 M     PLYMOUTH     MI  60.59
6/24/2014   7.08504E+22 BEACHWAY RESORT        SAUGATUCK    MI  1142.4
6/24/2014   7.08504E+22 PUMPERNICKELS EATERY   SAUGATUCK    MI  88.52
6/24/2014   7.08504E+22 DEMOND'S SUPER         DOUGLAS      MI  79.75
6/25/2014   7.08504E+22 DEMOND'S SUPER         DOUGLAS      MI  128.21

РЕДАКТИРОВАТЬ КОНЕЦ

DatetimeIndex: 852 записи, 2014-06-21 до 2020-01-23 Данные столбцы (всего 4 столбца): # Число столбцов ненулевое количество Dtype

--- ------ -------------- -----
0 транзакция_дата 852 ненулевое значение datetime64 [нс]
1 unique_mem_id 852 ненулевой объект
2 описание 852 ненулевой объект
3 количество 852 ненулевое значение с плавающей точкой64
типы: datetime64ns, float64 ( 1), object (2) использование памяти: 53,3+ КБ

Это словарь, который я пытался закодировать:

#test for transactions
from collections import defaultdict
transaction_dict = defaultdict(list)

for row in df_card.items():
    try:
        key = card_members
        value = df_card.amount
    except ValueError:
        continue

    transaction_dict[key] += value

print(transaction_dict)

Появляется ошибка: unhashable тип: «* 10 37 * .ndarray '

Я также пробовал df_card.iterrows (), но это также не удается: (

Ответы [ 3 ]

0 голосов
/ 27 марта 2020

Я думаю, вы можете использовать df_card.iterrows следующим образом:

transaction_dict = {}
for i, row in df_card.iterrows():
  key = row['unique_mem_id']
  val = row['amount']
  transaction_dict[key] = transaction_dict.get(key,0) + val

Надеюсь, это поможет!

0 голосов
/ 02 апреля 2020

Чтобы завершить это и было полезно для третьих лиц, вот мое окончательное решение: я использовал обходной путь, который был побочным продуктом следующих шагов, но будет аналогичен решениям, опубликованным Йосуа.

  1. create новый столбец, который помечает транзакции как «расходы» или «доход», а затем запускает if l oop, пока не достигнет первого «дохода», и добавьте его.

´

transaction_class_card = pd.Series([], dtype = 'object')
    for index, i in enumerate(df_card['transaction_category_name']):
        if i in card_inc:
            transaction_class_card[index] = "income"
        elif i in card_exp:
            transaction_class_card[index] = "expense"
        else:
            transaction_class_card[index] = "NOT_CLASSIFIED"
    df_card.insert(loc = len(df_card.columns), column = "transaction_class", value = transaction_class_card)

´

После добавления нового столбца я использую функцию «Последовательность», чтобы перебирать строки как кортежи и останавливаться, как только я нажимаю «доход», затем добавляются все «расходы» перед тем up.

Разделение фрейма данных

df_1 = df_card[['unique_mem_id', 'amount', 'transaction_class']][df_card['unique_mem_id'] == '70850441974905670928446']

Итерация с кортежами

cumulative_amount = []
amount_list = []
for row in df_1.itertuples():
   #access data using column names
   if row.transaction_class == "expense":
     #print(index, row.unique_mem_id, row.amount, row.transaction_class)
     amount_list.append(row.amount)
     cumulative_amount = np.cumsum(amount_list, axis = 0)
     #print(row.unique_mem_id, cumulative_amount)
   else:
  #print(f"stopped at user_ID: {row.unique_mem_id}, cumulative sum injected {cumulative_amount[-1]}")
                        break
                #print out the member id as part of the for-loop and and the last element of the list which is the amount to be injected
                print(f"unique_member_ID: {row.unique_mem_id}; initial injection needed in USD: {cumulative_amount[-1]}")

Печатает соответствующий member_ID и сумму их расходов. Надеюсь, эти варианты помогут:)

0 голосов
/ 27 марта 2020
dic = {}
for i in range(len(df)):
    key = df.at[i, 'unique_mem_id']
    if df.at[i, 'unique_mem_id'] in dic:
        dic[key] += df.at[i, 'description amount']
    else:
        dic[key] = df.at[i, 'description amount']

Попробуй это! Сначала мы создаем словарь. Затем мы пересекаем каждую строку кадра данных и проверяем, присутствует ли конкретный unique_mem_id в качестве ключа в словаре. Если это ключ, просто добавьте description_amount к этому ключу, иначе создайте новый ключ в словаре.

...