Панды Python выполняют операцию над набором различных столбцов

#python #pandas

Вопрос:

У меня есть фрейм данных с несколькими текстовыми столбцами и некоторыми значениями, я хотел бы сгруппировать результаты операции таким образом,чтобы «набор одних и тех же A, B и C» для изменения соотношения между q и значением, и я уверен, что есть лучший способ сделать это со встроенными функциями, но я еще не получил ответа.

 ID   A      B    C    q    value
1    Day    N    Wed  20    30
2    Noon   N    Wed  12    50
3    Day    S    Mon  30    13
4    Night  W    Sun  5      6
5    Night  E    Sun  20    20
6    Day    S    Wed  40    20
              ...
 

Я хочу сделать регрессию над q и значением над различными комбинациями [A,B,C]

 for uniqueA in df['A'].unique():
    for uniqueB in df.query('A == @uniqueA')['B'].unique():
        for uniqueC in df.query('A== @uniqueA and B == @uniqueB')['C'].unique():
            aux = df.query('A== @uniqueA and B == @uniqueB and C == @uniqueC')[['A','B','C','q',value]]
            aux = aux.groupby(['A','B','C','q'])['value'].sum().reset_index()
            # Make a regression on [x,y] ([q, value]) and save prediction results on a dataframe
 

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

Комментарии:

1. Каков ваш ожидаемый результат? Ваш код имеет недопустимый отступ и использует неопределенное значение переменной. Вы назначаете aux дважды, но никогда не используете его.

Ответ №1:

 res = df.apply(lambda r: r['q'] * r['value'] if r['value'] < 30 else r['q'] * r['value'] /2, axis=1)
 

Ответ №2:

Есть много способов сделать это.

Одним из способов является использование метода df.loc:

 condition = df['q'] < 30 # condition

df.loc[condition, "ans"]  = df['q'] * df['value']     # when true
df.loc[~condition, "ans"] = df['q'] * df['value'] / 2 # when false
 

Другой способ-использовать метод Numpy where:

 import numpy as np
df['ans'] = np.where(df['q']<30, df['q'] * df['value'], df['q'] * df['value'] / 2)
 

Синтаксис, чтобы вы понимали, что происходит, таков

 np.where(condition, operation when true, operation when false)
 

Ответ №3:

Для векторизованной операции вы можете использовать numpy.where , которая возвращает массив:

 import numpy as np

np.where(df['value'].lt(30),
         df['q'].mul(df['value']), 
         df['q'].mul(df['value']).div(2))

Out[162]: array([300., 300., 390.,  30., 400., 800.])
 

Чтобы назначить результат обратно в новый столбец в существующем фрейме данных:

 df['result'] = np.where(df['value'].lt(30),
         df['q'].mul(df['value']), 
         df['q'].mul(df['value']).div(2))
>>> df

   ID      A  B    C   q  value  result
0   1    Day  N  Wed  20     30   300.0
1   2   Noon  N  Wed  12     50   300.0
2   3    Day  S  Mon  30     13   390.0
3   4  Night  W  Sun   5      6    30.0
4   5  Night  E  Sun  20     20   400.0
5   6    Day  S  Wed  40     20   800.0