Pandas Ошибка: ошибка индексации при условном изменении значений строки ячейки - PullRequest
0 голосов
/ 23 марта 2020

Привет всем, я получаю сообщение об ошибке с индексированием / возвращением в цепочку вместо представления в Pandas. Вот мой код:

import pandas as pd 
duplicates = pd.read_csv("dupes_test.csv", parse_dates=["Updated At"])
dupe_df = pd.DataFrame(duplicates)
dupe_sorted = dupe_df.sort_values(['Email Address', 'Updated At'], ascending=False)

dataframe

cols_to_change = list(dupe_sorted.columns)
opt_out_count = 0 
unchanged_count = 0
error = 0 

Вот мой код для l oop:

for dupe in range (0, dupe_sorted.shape[0]):
    try:
        if dupe_sorted["Email Address"].iloc[dupe] == dupe_sorted["Email Address"].iloc[dupe + 1]:
            for col in cols_to_change:
                if dupe_sorted[col].iloc[dupe + 1] == 'Opt Out':
                    dupe_sorted[col].iloc[dupe] = "Opt Out"
                    opt_out_count +=1
        else:
            unchanged_count +=1
    except:
        error += 1 

print("We're Done")

Сообщение об ошибке:

//anaconda3/envs/DtownPlayground/lib/python3.6/site-packages/pandas/core/indexing.py:670: SettingWithCopyWarning: 
A value is trying to be set on a copy of a slice from a DataFrame

See the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy
  self._setitem_with_indexer(indexer, value)

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

print(f"Opted Out: {opt_out_count}, Unchanged: {unchanged_count}, Error: {error}")
Opted Out: 22, Unchanged: 8, Error: 1

Cleaned dataframe

В других случаях он не обновляет ни одно из значений. Наверное, я запутался, потому что я не использую цепную индексацию, и я не знаю, почему Pandas выдает мне это предупреждение. Кроме того, дайте мне знать, если мне нужно вставить фрейм данных в другом формате для простоты использования!

1 Ответ

0 голосов
/ 24 марта 2020

По сути, вы пытаетесь назначить одно значение ячейки для среза вашего фрейма данных и, следовательно, предупреждение:

dupe_sorted[col].iloc[dupe] = "Opt Out"

Обычно в Pandas операциях вы хотите назначить всю серию (т.е. , column) в одном вызове, известном как векторизованные операции , а не по ячейкам строки и столбца. Точно так же в операциях Numpy вы хотите назначить Ndarrays в одном вызове, а не назначать их по ячейкам.

Поэтому рассмотрите возможность объединения в версии DataFrame.shift тех же данных для захвата следующей строки ценности. Затем переназначьте с условными логами c, numpy.where, по каждому столбцу. И используйте функциональную форму оператора == с Series.eq, но оба метода действительны:

cols_to_change = dupe_sorted.columns.tolist()

# MERGE ON SHIFT FORWARD
dupe_sorted = dupe_sorted.join(dupe_sorted.shift(-1), how='left', rsuffix = '_')

# ITERATE ACROSS COLUMNS FOR SERIES ASSIGNMENT
for col in cols_to_change:
    dupe_sorted[col] = np.where((dupe_sorted['Email Address'].eq(dupe_sorted['Email Address_'])) &
                                (dupe_sorted[col+'_'].eq('Opt Out')),
                                'Opt Out',
                                dupe_sorted[col])

# REMOVE SHIFTED COLUMNS    
final_df = dupe_sorted.reindex(cols_to_change, axis='columns')
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...