У меня есть входные данные, как показано ниже. Здесь «пол» и «этапное происхождение» — две колонки. Я хотел бы заменить их значения, такие как 1,2,3 и т. д., категориальными значениями. Ex - 1 с мужчиной, 2 с женщиной
Файл сопоставления выглядит так, как показано ниже — пример 2 столбца.
Входные данные выглядят так, как показано ниже
Я ожидаю, что мой выходной фрейм данных будет выглядеть так
Я попытался сделать это, используя приведенный ниже код. Хотя код работает нормально, я не вижу замены. Не могли бы вы помочь мне с этим?
mapp = pd.read_csv('file2.csv')
data = pd.read_csv('file1.csv')
for col in mapp:
if col in data.columns:
print(col)
s = list(mapp.loc[(mapp[col].str.contains('^\d')==True)].index)
print("s is",s)
for i in s:
print("i is",i)
try:
value = mapp[col][i].split('. ')
print("value 0 is",value[0])
print("value 1 is",value[1])
if value[0] in data[col].values:
data.replace({col:{value[0]:value[1]}})
except:
print("column not present")
else:
print("No")
Обратите внимание, что я показал только два столбца, но в реальном времени их может быть более 600. Любой элегантный подход/предложения, чтобы сделать его простым, полезен. Поскольку у меня есть два отдельных CSV-файла, любые предложения по слиянию/объединению и т. д. также будут полезны, но обратите внимание, что мой файл сопоставления содержит значения «1. Мужской», «2. Женский». поэтому я использовал регулярное выражение
Также обратите внимание, что некоторые другие значения столбца также могут иметь значения сопоставления, начинающиеся с 1. Например: 1. Холост, 2. Женат, 3. Разведен и т. д.
С нетерпением жду вашей помощи
Используйте DataFrame.replace
с вложенными словарями - первый ключ определяет имя столбца для замены, а другие значения для замены создаются функцией Series.str.extract
:
df = pd.DataFrame({'Gender':['1.Male','2.Female', np.nan],
'Ethnicity':['1.Chinese','2.Indian','3.Malay']})
print (df)
Gender Ethnicity
0 1.Male 1.Chinese
1 2.Female 2.Indian
2 NaN 3.Malay
d = {x:df[x].str.extract(r'(\d+)\.(.+)').dropna().set_index(0)[1].to_dict() for x in df.columns}
print (d)
{'Gender': {'1': 'Male', '2': 'Female'},
'Ethnicity': {'1': 'Chinese', '2': 'Indian', '3': 'Malay'}}
df1 = pd.DataFrame({'Gender':[2,1,2,1],
'Ethnicity':[1,2,3,1]})
print (df1)
Gender Ethnicity
0 2 1
1 1 2
2 2 3
3 1 1
#convert to strings before replace
df2 = df1.astype(str).replace(d)
print (df2)
Gender Ethnicity
0 Female Chinese
1 Male Indian
2 Female Malay
3 Male Chinese
ооо вложенный дикт. Это аккуратно. Не знала, что его тоже можно использовать
@jezrael - есть несколько столбцов, которые не заменяются. Я проверил регулярное выражение, и оно, кажется, работает. Можете ли вы придумать какую-либо причину, кроме регулярного выражения, почему оно не может заменить?
@SELVA - Сложный вопрос, похоже, проблема с данными. Поэтому лучше всего проверить, совпадают ли имена столбцов (точно такие же имена) - например. на print (sorted(d.keys()))
с print (sorted(df1.columns))
, если все совпадает, то определите, какие столбцы не заменены, и проверьте print (d['col not repalaced1'])
, print (d['col not repalaced2'])
с print (df1['col not repalaced1'].astype(str).unique())
, print (df1['col not repalaced2'].astype(str).unique())
Когда я печатаю один из столбцов фрейма данных, значение отображается как 1,0 в jupyter, тогда как в Excel/csv оно равно 1, может ли это быть проблемой?
Я имею в виду, что в моем фрейме данных также есть столбцы, которых нет в файле сопоставления. но это не должно быть проблемой, так как мы сопоставляем и заменяем на основе имен?
@SELVA - да, потому что заменены номера строк, решение должно быть в pandas 0.240 от df1.astype('Int64').astype(str).replace(d)
@SELVA - Нет, это не проблема, если другие столбцы, только необходимо проверить, нет ли опечатки в столбцах, которые должны быть одинаковыми.
Хорошо, я вижу, что эти ключи успешно генерируются в словаре (d), но одна замена не происходит
Другой способ конвертировать в int64? df1.astype('Int64').astype(str).replace(d) этот оператор выдает ошибку
@SELVA - Итак, сопоставляем print (d['col not repalced1']) with print (df1['col not replaced1'].astype(str).unique())
для всех проблемных значений?
Давайте продолжить обсуждение в чате.
Если записи всегда в порядке (1.XXX,2.XXX...
), используйте:
m=df1.apply(lambda x: x.str[2:])
n=df2.sub(1).replace(m)
print(n)
gender ethderived
0 Female Chinese
1 Male Indian
2 Male Malay
3 Female Chinese
4 Male Chinese
5 Female Indian
Вы можете просмотреть свои столбцы и сначала создать словарь, а затем применить
.map
, чтобы заменить ключ парой значений. Не на ноутбуке, поэтому я не могу показать пример, но я бы сделал это так.