Нарезка данных в Python не работает в функции, но работает автономно - PullRequest
0 голосов
/ 15 октября 2019

Я проверил похожие вопросы о разделении DF в Python, но они не объяснили несоответствие, которое я вижу в моем упражнении.

Код работает с фреймом данных известных алмазов. Верхние строки фрейма данных:

     carat        cut color clarity  depth  table  price     x     y     z
0     0.23      Ideal     E     SI2   61.5   55.0    326  3.95  3.98  2.43
1     0.21    Premium     E     SI1   59.8   61.0    326  3.89  3.84  2.31
2     0.23       Good     E     VS1   56.9   65.0    327  4.05  4.07  2.31

Мне нужно создать функцию среза, которая принимает 4 аргумента: DataFrame 'df', столбец этого DataFrame 'col', метка другого столбца 'label'и два значения' val1 'и' val2 '. Функция возьмет кадр и выведет записи столбца, указанного аргументом «label», для которых строки столбца «col» больше, чем «val1», и меньше, чем «val2».

Следующий отдельный фрагмент кода дает мне правильный ответ:

diamonds.loc[(diamonds.carat > 1.1) & (diamonds.carat < 1.4),['price']]

, и я получаю цену из строк, где значение в каратах находится между 1,1 и 1,4.

Однако,когда я пытаюсь использовать этот синтаксис в функции, он не работает, и я получаю сообщение об ошибке.

Функция:

def slice2(df,col,output_label,val1,val2):
    res = df.loc[(col > val1) & (col < val2), ['output_label']]
    return res

Вызов функции:

slice2(diamonds,diamonds.carat,'price',1.1,1.4)

Ошибка:

"None of [['output_label']] are in the [columns]" 

Сообщение о полной трассировке:

---------------------------------------------------------------------------
KeyError                                  Traceback (most recent call last)
<ipython-input-64-adc582faf6cc> in <module>()
----> 1 exercise2(test_df,test_df.carat,'price',1.1,1.4)

<ipython-input-63-556b71ba172d> in exercise2(df, col, output_label, val1, val2)
      1 def exercise2(df,col,output_label,val1,val2):
----> 2     res = df.loc[(col > val1) & (col < val2), ['output_label']]
      3     return res
/Users/jojo/Library/Enthought/Canopy/edm/envs/User/lib/python3.5/site-packages/pandas/core/indexing.py in __getitem__(self, key)
   1323             except (KeyError, IndexError):
   1324                 pass
-> 1325             return self._getitem_tuple(key)
   1326         else:
   1327             key = com._apply_if_callable(key, self.obj)
/Users/jojo/Library/Enthought/Canopy/edm/envs/User/lib/python3.5/site-packages/pandas/core/indexing.py in _getitem_tuple(self, tup)
    839 
    840         # no multi-index, so validate all of the indexers
--> 841         self._has_valid_tuple(tup)
    842 
    843         # ugly hack for GH #836
/Users/jojo/Library/Enthought/Canopy/edm/envs/User/lib/python3.5/site-packages/pandas/core/indexing.py in _has_valid_tuple(self, key)
    187             if i >= self.obj.ndim:
    188                 raise IndexingError('Too many indexers')
--> 189             if not self._has_valid_type(k, i):
    190                 raise ValueError("Location based indexing can only have [%s] "
    191                                  "types" % self._valid_types)
/Users/jojo/Library/Enthought/Canopy/edm/envs/User/lib/python3.5/site-packages/pandas/core/indexing.py in _has_valid_type(self, key, axis)
   1416 
   1417                 raise KeyError("None of [%s] are in the [%s]" %
-> 1418                                (key, self.obj._get_axis_name(axis)))
   1419 
   1420             return True
KeyError: "None of [['output_label']] are in the [columns]" 

Я не очень продвинут в Python, и после просмотра этого кода какое-то время я не смог понятьв чем проблема. Возможно, я не замечаю чего-то очевидного здесь и был бы признателен за любые указания о том, как заставить функцию работать или как ее переделать, чтобы она давала тот же результат, что и однострочный код.

Спасибо

1 Ответ

4 голосов
/ 15 октября 2019

В вашей функции

def slice2(df,col,output_label,val1,val2):
    res = df.loc[(col > val1) & (col < val2), ['output_label']]
    return res

вы ищете столбец с именем 'output_label' вместо использования вашего параметра (вы назначаете его значение напрямую, а не используете свое значение! )

Это должно работать:

def slice2(df,col,output_label,val1,val2):
    res = df.loc[(col > val1) & (col < val2), [output_label]] # notice that there are not quotes
    return res
...