умножение и суммирование определенных столбцов на основе имени панды питона - PullRequest
0 голосов
/ 16 мая 2018

У меня есть небольшой пример данных:

import pandas as pd
d = {
  'measure1_x': [10,12,20,30,21],
  'measure2_x':[11,12,10,3,3],
  'measure3_x':[10,0,12,1,1],
  'measure1_y': [1,2,2,3,1],
  'measure2_y':[1,1,1,3,3],
  'measure3_y':[1,0,2,1,1]
}
df = pd.DataFrame(d)
df = df.reindex_axis([
    'measure1_x','measure2_x', 'measure3_x','measure1_y','measure2_y','measure3_y'
], axis=1) 

это выглядит так:

      measure1_x  measure2_x  measure3_x  measure1_y  measure2_y  measure3_y
          10          11          10           1           1           1
          12          12           0           2           1           0
          20          10          12           2           1           2
          30           3           1           3           3           1
          21           3           1           1           3           1

Я создал имена столбцов почти одинаковыми, за исключением '_x' и '_y'чтобы помочь определить, какая пара должна умножаться: я хочу умножить пару с тем же именем столбца, когда игнорируются '_x' и '_y', затем я хочу суммировать числа, чтобы получить общее число, имейте в виду мой фактический набор данныхогромен, и столбцы не в этом идеальном порядке, поэтому это наименование является способом определения правильных пар для умножения:

total = measure1_x * measure1_y + measure2_x * measure2_y + measure3_x * measure3_y

желаемый вывод:

measure1_x  measure2_x  measure3_x  measure1_y  measure2_y  measure3_y   total

 10          11          10           1           1           1           31 
 12          12           0           2           1           0           36 
 20          10          12           2           1           2           74
 30           3           1           3           3           1          100
 21           3           1           1           3           1           31

моя попытка и мыслительный процесс, но не может быть продолжен с точки зрения синтаксиса:

#first identify the column names that has '_x' and '_y', then identify if 
#the column names are the same after removing '_x' and '_y', if the pair has 
#the same name then multiply them, do that for all pairs and sum the results 
#up to get the total number

for colname in df.columns:
if "_x".lower() in colname.lower() or "_y".lower() in colname.lower():
    if "_x".lower() in colname.lower():  
        colnamex = colname
    if "_y".lower() in colname.lower():
        colnamey = colname

    #if colnamex[:-2] are the same for colnamex and colnamey then multiply and sum

Ответы [ 2 ]

0 голосов
/ 16 мая 2018

filter + np.einsum

Я подумал, что на этот раз я попробую что-то немного другое -

  • получите столбцы _x и _y отдельно
  • сделать товар-сумму.Это очень легко определить с помощью einsumfast ).

df = df.sort_index(axis=1) # optional, do this if your columns aren't sorted

i = df.filter(like='_x') 
j = df.filter(like='_y')
df['Total'] = np.einsum('ij,ij->i', i, j) # (i.values * j).sum(axis=1)

df
   measure1_x  measure2_x  measure3_x  measure1_y  measure2_y  measure3_y  Total
0          10          11          10           1           1           1     31
1          12          12           0           2           1           0     36
2          20          10          12           2           1           2     74
3          30           3           1           3           3           1    100
4          21           3           1           1           3           1     31

A слегкаболее надежная версия, которая отфильтровывает нечисловые столбцы и заранее выполняет утверждение -

df = df.sort_index(axis=1).select_dtypes(exclude=[object])
i = df.filter(regex='.*_x') 
j = df.filter(regex='.*_y')

assert i.shape == j.shape

df['Total'] = np.einsum('ij,ij->i', i, j)

Если утверждение не выполнено, предположения 1), что ваши столбцы являются числовыми, и 2) число x и yСтолбцы, которые равны, как предполагает ваш вопрос, не сохраняются для вашего фактического набора данных.

0 голосов
/ 16 мая 2018
  • Используйте df.columns.str.split для создания нового MultiIndex
  • Используйте prod с axis и level аргументами
  • Использовать sum с axis аргументом
  • Используйте assign для создания нового столбца

df.assign(
    Total=df.set_axis(
        df.columns.str.split('_', expand=True),
        axis=1, inplace=False
    ).prod(axis=1, level=0).sum(1)
)

   measure1_x  measure2_x  measure3_x  measure1_y  measure2_y  measure3_y  Total
0          10          11          10           1           1           1     31
1          12          12           0           2           1           0     36
2          20          10          12           2           1           2     74
3          30           3           1           3           3           1    100
4          21           3           1           1           3           1     31

Ограничить фрейм данных только столбцами, которые выглядят как 'meausre[i]_[j]'

df.assign(
    Total=df.filter(regex='^measure\d+_\w+$').pipe(
        lambda d: d.set_axis(
            d.columns.str.split('_', expand=True),
            axis=1, inplace=False
        )
    ).prod(axis=1, level=0).sum(1)
)

Debugging

Посмотрите, дает ли это вам правильные итоги

d_ = df.copy()
d_.columns = d_.columns.str.split('_', expand=True)

d_.prod(axis=1, level=0).sum(1)

0     31
1     36
2     74
3    100
4     31
dtype: int64
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...