Сохраните некоторые конкретные значения в фрейме данных и установите для остальных значение нуля

#python #python-3.x #function #dataframe #apply

#python #python-3.x #функция #фрейм данных #применить

Вопрос:

Я создал функцию следующим образом

 def element(x):
    return x*1 if x > 0.09 else x*0
 

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

     index   FACTOR1     FACTOR2     FACTOR3
0   ECON1   0.0955037   0.0297977   0.0148448
1   ECON2   0.00505775  0.142272    0.0516773
2   ECON2   0.0360157   0.0115226   0.133393
3   FOOD1   0.106315    0.000673806 0.0264848
4   FOOD2   0.0188154   0.0344419   0.138877
5   FOOD3   0.00941108  0.1851     0.000474615
 

Я хотел бы сохранить значения, превышающие пороговое значение (скажем, 0.09 — см. Функцию выше), а для других установить нули.

Я применил следующую функцию, но она не сработала

 display(df.apply(element, subset=Variable_Names) )
 

Я получаю сообщение об ошибке

 TypeError: ("element() got an unexpected keyword argument 'subset'", 'occurred at index FACTOR1')
 

Ответ №1:

Используется df.select_dtypes для идентификации только numeric столбцов из df .

Затем используйте numpy.where для проверки значений, которые превышают пороговое значение, и присвоите остальным 0 :

 In [2897]: import numpy as np

In [2915]: threshold = 0.09

In [2898]: cols = df.select_dtypes('number').columns

In [2911]: df[cols] = np.where(df[cols].gt(threshold), df[cols], 0)

In [2912]: df
Out[2912]: 
   index   FACTOR1   FACTOR2   FACTOR3
0  ECON1  0.095504  0.000000  0.000000
1  ECON2  0.000000  0.142272  0.000000
2  ECON2  0.000000  0.000000  0.133393
3  FOOD1  0.106315  0.000000  0.000000
4  FOOD2  0.000000  0.000000  0.138877
5  FOOD3  0.000000  0.185100  0.000000
 

Ответ №2:

Прежде всего, посмотрите документацию по методу apply. Если вы вызываете df.apply(element, subset=Variable_Names) подобным образом, вы предоставляете дополнительный аргумент subset функции element (и это не ожидается этой функцией).

Во-вторых, вы должны выбрать только числовую часть вашего фрейма данных, чтобы применить свою функцию:

 df.loc[:, Variable_Names]
 

В-третьих, если вы примените эту функцию к своему фрейму данных точно так же, как это, вы получите

 ValueError: ('The truth value of a Series is ambiguous. Use a.empty, a.bool(), a.item(), a.any() or a.all().', 'occurred at index FACTOR1')
 

потому что apply передает столбцы (по умолчанию) или строки (с опцией axis=1 ) в вашу функцию, которая не адаптирована для ввода массива (неравенство массива и числа возвращает массив логических значений, в то время if как ожидает только одно значение).

Итак, что вы можете сделать, это:

  1. используйте applymap():
 df.loc[:, Variable_Names] = df.loc[:, Variable_Names].applymap(element)
 
  1. используйте np.vectorize():
 df.loc[:, Variable_Names] = df.loc[:, Variable_Names].apply(np.vectorize(element))
 

оба дают желаемый результат:

     index   FACTOR1     FACTOR2     FACTOR3
0   ECON1   0.095504    0.000000    0.000000
1   ECON2   0.000000    0.142272    0.000000
2   ECON2   0.000000    0.000000    0.133393
3   FOOD1   0.106315    0.000000    0.000000
4   FOOD2   0.000000    0.000000    0.138877
5   FOOD3   0.000000    0.185100    0.000000