Функция Python не работает в Pandas Dataframe при подмножестве в цикле

Я создал ряд очень простых функций, которые хочу применить к DataFrame pandas. Например:

def dir_flag(start, end):
   try:
      if start < end:
         return '+'
      else:
         return '-'
   except:
      return 'NA'

Я импортировал файл csv в DataFrame под названием «mydata» и могу применить свою функцию:

mydata['direction'] = mydata.apply(lambda x: dir_flag(x['START_NODE'], x['END_NODE']), axis=1)

Это прекрасно работает. Однако, когда я пытаюсь применить эту или аналогичные функции к Pandas DataFrame, созданному как подмножество «mydata», я получаю следующую ошибку: ValueError: Wrong number of items passed 2, placement implies 0. FYI mydata содержит 3-х уровневый мультииндекс.

Подмножество происходит в следующем цикле:

idx = pd.IndexSlice

idx1_levels = mydata.index.unique(level='idx_level1').tolist()

for x in idx1_levels:
   idx1_subset = mydata.loc[idx[x], ['START_NODE','END_NODE']]
   idx2_levels = idx1_subset.index.unique(level='idx_level2').tolist()
   for y in idx2_levels:

       idx2_subset = idx1_subset.loc[idx[y]]

       idx3_subset = idx2_subset.loc[idx[slice(None), 1.0], ['START_NODE','END_NODE']]

       idx3_subset['direction'] = journey_offset.apply(lambda a: dir_flag(a['START_NODE'], a['END_NODE']), axis=1)

Кажется, проблема возникает из-за оператора idx3_subset = idx2_subset.loc[idx[slice(None), 1.0], ['START_NODE','END_NODE']], так как я с радостью могу применить свою функцию к idx2_subset.

Обратите внимание, что я новичок в Python и сильно подозреваю, что есть лучший способ разбить мой исходный DataFrame на подмножества (например, используя метод groupby). Я очень рад получить предложения о том, как можно улучшить общее подмножество, но, пожалуйста, могу ли я ответить на конкретный вопрос о том, почему это не работает, поскольку это поможет мне лучше понять, как работают Pandas DataFrames.

Упрощенная версия прочитанного csv:

idx_level1|idx_level2|idx_level3|idx_level4|START_NODE|END_NODE
353386066294006|1142|2018-09-20T07:57:26Z|1|18260004567689|18260005575180
353386066294006|1142|2018-09-20T07:57:26Z|2|18260004567689|18260004240718
353386066294006|1142|2018-09-20T07:57:26Z|3|18260005359901|18260004567689
353386066294006|1142|2018-09-20T07:57:31Z|1|18260004567689|18260005575180
353386066294006|1142|2018-09-20T07:57:31Z|2|18260004567689|18260004240718
353386066294006|1142|2018-09-20T07:57:31Z|3|18260005359901|18260004567689
353386066294006|1142|2018-09-20T07:57:36Z|1|18260004567689|18260005575180
353386066294006|1142|2018-09-20T07:57:36Z|2|18260004567689|18260004240718
353386066294006|1142|2018-09-20T07:57:36Z|3|18260005359901|18260004567689
353386066736543|22|2018-04-17T07:08:23Z|||
353386066736543|22|2018-04-17T07:08:24Z|||
353386066736543|22|2018-04-17T07:08:25Z|||
353386066736543|22|2018-04-17T07:08:26Z|||
353386066736543|403|2018-07-02T16:55:07Z|1|18260004580350|18260005235340
353386066736543|403|2018-07-02T16:55:07Z|2|18260005235340|18260005141535
353386066736543|403|2018-07-02T16:55:07Z|3|18260005235340|18260005945439
353386066736543|403|2018-07-02T16:55:07Z|4|18260006215338|18260005235340
353386066736543|403|2018-07-02T16:55:07Z|5|18260004483352|18260005945439
353386066736543|403|2018-07-02T16:55:07Z|6|18260004283163|18260006215338
353386066736543|403|2018-07-02T16:55:01Z|1|18260004580350|18260005235340
353386066736543|403|2018-07-02T16:55:01Z|2|18260005235340|18260005141535
353386066736543|403|2018-07-02T16:55:01Z|3|18260005235340|18260005945439
353386066736543|403|2018-07-02T16:55:01Z|4|18260006215338|18260005235340
353386066736543|403|2018-07-02T16:55:01Z|5|18260004483352|18260005945439
353386066736543|403|2018-07-02T16:55:01Z|6|18260004283163|18260006215338

И код, который я использую для чтения, выглядит следующим образом:

mydata = pd.read_csv('/myloc/my_simple_data.txt', sep='|', 
 dtype = {'idx_level1': 'int',
        'idx_level2': 'int',
        'idx_level3': 'str',
        'idx_level4': 'float',
        'START_NODE': 'str',
        'END_NODE': 'str'},
 parse_dates = ['idx_level3'],
 index_col=['idx_level1','idx_level2','idx_level3','idx_level4'])

Интересно, что при сборке этого набора данных - я понял, что ошибка возникает только тогда, когда у меня есть данные, в которых есть нули - NB, это включает в себя нули на одном уровне индекса. Индекс здесь законно равен нулю, т.е. это НЕ ошибка данных.

Не могли бы вы включить образец своего фрейма данных? Убедитесь, что ваша ошибка воспроизводима здесь, и что у тех, кто пытается помочь решить вашу проблему, есть вся необходимая информация.

rahlf23 17.12.2018 17:28

Привет, Rahlf23, я отредактировал, чтобы включить пример набора данных - теперь это заставляет меня думать, что проблема связана с нулями на одном уровне индекса - но, учитывая, что это может быть так, как я могу обойти ошибки?

paul frith 17.12.2018 18:12

Привет! Ваш пример кода не работает, поскольку idx не определен. Однако кажется, что действительно должен быть лучший способ подмножества вашего фрейма данных. Не могли бы вы сказать мне, какое подмножество вы пытаетесь выбрать и почему? Я думаю, тогда мы сможем помочь тебе лучше

Jondiedoop 17.12.2018 20:34

Кроме того, что такое journey_offset? Убедитесь, что ваши данные и код компилируются и запускаются из наших пустых сред Python. См. минимальный воспроизводимый пример.

Parfait 17.12.2018 20:39

Это крики XY проблема. Вы должны попытаться полностью избежать циклов for с помощью Pandas. Если вы поделитесь (возможно, в новом вопросе), чего пытаетесь достичь с помощью минимальный воспроизводимый пример, у вас больше шансов найти хорошее решение.

jpp 18.12.2018 01:49

Извинения - сделал пару ошибок, пытаясь сделать свой код более общим для этого вопроса - отредактировал и считаю, что исправил проблемы. Мне самому удалось решить непосредственную проблему этого вопроса, заменив значения NaN на самом низком уровне индекса на значение, однако я все еще хочу знать, почему значения NULL вызывают здесь проблему.

paul frith 18.12.2018 01:59
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
0
6
578
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Таким образом, проблема возникает из-за выполнения индексного среза на мультииндексе, где один из уровней содержит нули. Поэтому решение состоит в том, чтобы заменить нулевое значение константой:

mydata = pd.read_csv('/myloc/my_simple_data.txt', sep='|', 
 dtype = {'idx_level1': 'int',
        'idx_level2': 'int',
        'idx_level3': 'str',
        'idx_level4': 'float',
        'START_NODE': 'str',
        'END_NODE': 'str'},
 parse_dates = ['time']);

mydata.idx_level4 = mydata.idx_level4.fillna(1.0)

mydata.set_index(['idx_level1','idx_level2','idx_level3','idx_level4'], inplace=True)

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

Другие вопросы по теме