Эффективная фильтрация столбцов - PullRequest
0 голосов
/ 24 сентября 2018

У меня есть следующий фрейм данных:

item         = ['item1','item2','item3']
amount       = [500,200,800]
feature_2020 = [18,32,34]
feature_2030 = [28,42,44]
feature_2040 = [38,52,54]
df = pd.DataFrame({'index':item,'amount':amount,'feature_2020': feature_2020,'feature_2030':feature_2030,'feature_2040':feature_2040})
df.index= df['index']
print(df)



         amount   feature_2020  feature_2030  feature_2040  index
index                                                         
item1     500            18            28            38     item1
item2     200            32            42            52     item2
item3     800            34            44            54     item3

Я хочу эффективно сделать следующее (я уже могу это сделать, но очень плохо):

  • Для каждогоВ столбце Feature (Feature_2020, Feature_2030, Feature_2040) я хочу отфильтровать значения строго до 20, от 20 до 40 и от 40.
  • После применения этого фильтра я хочу вычислить суммустолбец количества оставшихся предметов для каждой категории, отфильтрованной выше.

Ожидаемый результат:

inf20            = [500,1000,0]
supequal20_inf40 = [0,500,1000]
supequal40       = [0,500,1000]
index            = ['inf20','supequal20_inf40','supequal40']
result = pd.DataFrame({'sum_feature_2020':inf20,'sum_feature_2030':supequal20_inf40,'sum_feature_2040': supequal40,'index':index})
result.index= result['index']
print(result)



              sum_feature_2020  sum_feature_2030    sum_feature_2040                                                     
inf20               500                0                  0
supequal20_inf40    1000               500                500
supequal40           0                 1000               1000

Есть ли способ сделать эту фильтрацию и операцию эффективным способом?

Большое спасибо за вашу помощь,

Ответы [ 2 ]

0 голосов
/ 24 сентября 2018

Альтернативный способ, менее обобщенный способ

x = df.set_index('amount')[[ 'feature_2020', 'feature_2030', 'feature_2040']]

r1 = x.lt(20).mul(x.index, axis=0).sum()
r2 = (x.ge(20) & x.lt(40)).mul(x.index, axis=0).sum()
r3 = x.ge(40).mul(x.index, axis=0).sum()

df_f = pd.concat([r1,r2,r3], 1).T

    feature_2020    feature_2030    feature_2040
0   500             0               0
1   1000            500             500
2   0               1000            1000
0 голосов
/ 24 сентября 2018

Сначала я бы растопил это, чтобы поместить все значения, которые мы хотим поместить в один столбец, затем я бы скопировал его, используя pd.cut, а затем развернул бы назад.

d2 = df.melt(["index", "amount"])
d2["binned"] = pd.cut(d2.value, [0, 20, 40, np.inf], right=False)
out = d2.pivot_table(index="binned", columns="variable",
                     values="amount", aggfunc=sum).fillna(0)

который дает мне

In [172]: out
Out[172]: 
variable      feature_2020  feature_2030  feature_2040
binned                                                
[0.0, 20.0)          500.0           0.0           0.0
[20.0, 40.0)        1000.0         500.0         500.0
[40.0, inf)            0.0        1000.0        1000.0

в виде

In [173]: d2
Out[173]: 
   index  amount      variable  value        binned
0  item1     500  feature_2020     18   [0.0, 20.0)
1  item2     200  feature_2020     32  [20.0, 40.0)
2  item3     800  feature_2020     34  [20.0, 40.0)
3  item1     500  feature_2030     28  [20.0, 40.0)
4  item2     200  feature_2030     42   [40.0, inf)
5  item3     800  feature_2030     44   [40.0, inf)
6  item1     500  feature_2040     38  [20.0, 40.0)
7  item2     200  feature_2040     52   [40.0, inf)
8  item3     800  feature_2040     54   [40.0, inf)
...