#python #pandas #dataframe
Вопрос:
Поэтому я пытаюсь найти частичную строку в определенном столбце моего csv-файла. Если это соответствует определенному условию, он напишет что-то еще в другой колонке.
Например:
Letter Grade Percentage A Ninety Five Percent C Seventy Three Percent B Eighty Two Percent
Столбец «Процент» всегда будет иметь один и тот же формат «Девяносто пять процентов», то есть число в словах Процент.
Я хочу, чтобы можно было открыть файл csv, чтобы python проанализировал столбец процентов для первого слова, например, если он содержит «Девяносто», то он назначит «А» в столбце «класс букв», если он содержит «Восемьдесят», затем » Б » в классе букв и так далее, и так далее.
Это мой текущий код:
import pandas as pd df = pd.DataFrame(pd.read_csv(r'file.csv', dtype=str)) A = 'Ninety' B = 'Eighty' C = 'Seventy' D = 'Sixty' if df[df['Percentage'].isin(A)]: df['Letter Grade'] = df['Letter Grade'].str.replace['', 'A', regex=False] elif df[df['Percentage'].isin(B)]: df['Letter Grade'] = df['Letter Grade'].str.replace['', 'B', regex=False] elif df[df['Percentage'].isin(C)]: df['Letter Grade'] = df['Letter Grade'].str.replace['', 'C', regex=False] elif df[df['Percentage'].isin(D)]: df['Letter Grade'] = df['Letter Grade'].str.replace['', 'D', regex=False] else: df['Letter Grade'] = df['Letter Grade'].str.replace['', 'F', regex=False] df.to_csv(r'file.csv', index=False)
В настоящее время он выдает мне эту ошибку: The truth value of a DataFrame is ambiguous.
Ответ №1:
Вы можете использовать dictionary
split
map
для этого функцию и
grades={'Ninety':'A', 'Eighty':'B', 'Seventy':'C', 'Sixty':'D'} df['Letter Grade'] = df.Percentage.str.split(expand=True)[0].map(grades)
Комментарии:
1. если это ваше решение, то примите его как ответ. Спасибо
Ответ №2:
Попробуйте с numpy.select
:
import numpy as np df["Letter Grade"] = np.select([df["Percentage"].str.contains(A), df["Percentage"].str.contains(B), df["Percentage"].str.contains(C), df["Percentage"].str.contains(D)], ["A","B","C","D"])
Альтернативно с findall
и map
:
mapper = {"Ninety": "A", "Eighty": "B", "Seventy": "C", "Sixty": "D"} df["Letter Grade"] = df["Percentage"].str.findall("|".join(mapper.keys())).str[0].map(mapper)
Ответ №3:
ответ @not_speshal великолепен, но на самом деле он не объясняет точную проблему, с которой вы столкнулись.
isin
фактически возвращает фрейм данных с перечислением каждого столбца и независимо от того, была ли строка найдена как целый элемент (например, он найдет 'Ninenty'
, но не «Девять x»).
Вместо этого вы можете использовать .str.contains(...)
столбец, который вернет копию столбца, в котором находится каждый элемент True
, если строка в столбцах содержала вашу строку, False
в противном случае. Затем вы можете вызвать .any()
результирующую серию , которая вернется True
, если в серии есть один элемент True
, и она вернется False
, если в True
серии нет значений (не было совпадающих строк).
Вместо
if df[df['Percentage'].isin(A)]:
ты хочешь:
if df['Percentage'].str.contains('Ninety').any():