Ошибка фильтрации Python.Ключ логической серии будет переиндексирован для соответствия индексу DataFrame. - PullRequest
0 голосов
/ 01 октября 2018

Я изо всех сил пытаюсь заставить этот код, который я написал, работать.Я знаю, что это, вероятно, легко исправить, но я не могу заставить его работать правильно.По сути, я хочу создать логическую маску на фрейме данных pandas, который возвращает только те строки, в которых значения в «Actual Manufacturer» или «Actual Collection» существуют в «PqaQuestion».Это хорошо работает с одним набором критериев, но добавление в несколько критериев портит вещи немного.Кажется, я не могу вставить туда оператор «или», не вызвав предупреждение пользователя: логический ключ серии будет переиндексирован, чтобы соответствовать индексу фрейма данных, что портит вывод.Если кто-то может помочь решить эту проблему, но также помочь мне понять, почему это происходит, я был бы очень признателен.Я видел другие посты на эту тему, но ни одного, которые объясняют это, и я не могу адаптировать другие посты к моей собственной ситуации.

names= ['PqaPrSKU', 'PrName', 'White Label Manufacturer', 'White Label Collection', 'Actual Manufacturer', 'Actual MaID', 'Actual Collection', 'PqaID', 'PqaQuestion', 'UpdatedQuestion', 'PanID', 'PanAnswer', 'UpdatedAnswer', 'DateAdded', 'PrBclgID']


def match_function(column1_value, column2_value, column3_value):
     return (column2_value is not None) and (column1_value is not None) and (column3_value is not None) and (str(column2_value).lower() in str(column1_value).lower()) or (str(column3_value).lower() in str(column1_value).lower())


import pandas as pd
df = pd.read_csv('Bucket61(8.22).csv', names= names, skipinitialspace=True, skiprows=1)
#print(df.from_records(data))

indexer = df.apply(lambda row: match_function(row["PqaQuestion"], row["Actual Collection"], row["Actual Manufacturer"]), axis=1)


filtered_df = df[indexer]

print(filtered_df[indexer])
#print(df[indexer])
from pandas import ExcelWriter

writer = ExcelWriter('ScrubbedQATemplate.xlsx')
filtered_df.to_excel(writer, 'Sheet1')
writer.save()

1 Ответ

0 голосов
/ 01 октября 2018

Вы точно не объяснили, чего пытается достичь match_function, но по возможности следует избегать pd.DataFrame.apply.Это не что иное, как тонко завуалированный цикл.

Давайте вместо этого попробуем преобразовать критерии в match_function в маску логического ряда:

def match_function(column1_value, column2_value, column3_value):
     return (column2_value is not None) and (column1_value is not None) and \
            (column3_value is not None) and \
            (str(column2_value).lower() in str(column1_value).lower()) or \
            (str(column3_value).lower() in str(column1_value).lower())

# match_function(row["PqaQuestion"], row["Actual Collection"], row["Actual Manufacturer"])

Вот одна попытка:

cols = ['PqaQuestion', 'Actual Collection', 'Actual Manufacturer']

A = df[cols].astype(str).values

m1 = df[cols].notnull().all(1)
m2 = np.array([j.lower() in i.lower() for i, j, k in A])
m3 = np.array([k.lower() in i.lower() for i, j, k in A])

filtered_df = df[m1 & (m2 | m3)]

Несколько замечаний:

  1. Мы используем векторизованные операции с помощью & / |, а не скалярные операции and / or, которые будут применяться с построчными операциями.
  2. m1 объединяет ваши первые 3 условия в одно с помощью pd.DataFrame.all.
  3. Логические условия в сериях Pandas и массивы NumPy можно комбинировать с помощью & /| операторов.
...