Изменение значения столбца Pandas Dataframe путем проверки состояния другого столбца

1

В моем Dataframe есть 2 столбца, один содержит блок, а другой - значение.

     df4 = pd.DataFrame({'D': ['g', 'Kg', 'l', 'ml'],
                         'F': ['500', '1', '1', '1000']})

Я пытаюсь преобразовать Kg в g и l в мл. Я попробовал это:

    for row in final_df.iterrows():
        if final_df['D']=='Kg': 
            final_df['F']=(final_df['F']*1000)
            final_df['D']='g'
        elif final_df['D']=='l':
            final_df['F']=(final_df['F']*1000)
            final_df['D']='ml'

Ожидаемый результат:

    D   F
    g   500
    g   1000
    ml  1000
    ml  1000




    ValueError: The truth value of a Series is ambiguous. Use a.empty, a.bool(), a.item(), a.any() or a.all().
  • 0
    Не могли бы вы опубликовать ожидаемый результат в тегах кода тоже один раз.
Теги:
pandas
dataframe

5 ответов

0

С комбинацией функций to_numeric + isin + replace:

In [215]: df = pd.DataFrame({'D': ['g', 'Kg', 'l', 'ml'], 'F': ['500', '1', '1', '1000']}) 

In [216]: df.F = pd.to_numeric(df.F)

In [217]: df.loc[df.D.isin(['Kg','l']), 'F'] *= 1000

In [218]: df.D.replace(to_replace={'Kg': 'g', 'l': 'ml'}, inplace=True)

In [219]: df
Out[219]: 
    D     F
0   g   500
1   g  1000
2  ml  1000
3  ml  1000
0

Вы можете использовать это:

df['F'] = np.where(df['D'].isin(['Kg','l']), df['F'].astype(int) * 1000, df['F'])
df['D'] = np.where(df['D']=='Kg', 'g', df['D'])
df['D'] = np.where(df['D']=='l', 'ml', df['D'])

Выход:

    D     F
0   g   500
1   g  1000
2  ml  1000
3  ml  1000
0

В дополнение к ответу np.where, используя np.where, вы также можете рассмотреть df.mask, который является методом специально для обновления столбца, где условие истинно:

df4['F'] = pd.to_numeric(df4['F'])
df4['F'].mask(df4['D'].isin(['Kg', 'l']), df4['F'] * 1000, inplace=True)
#    D     F
#0   g   500
#1  Kg  1000
#2   l  1000
#3  ml  1000
0

Итак, пара проблем с этим кодом Dheeraj. Я попытаюсь объяснить их один за другим.

  • Первое, что вы пытаетесь установить ваши значения числового типа в столбце F как объекты String, помещая их внутри кавычек и пытающихся разделить строку на целое число. Поэтому, очевидно, это даст вам ошибку.
  • Во-вторых, вы пытаетесь поставить условный оператор на весь столбец, используя final_df ['D'] == 'Kg'; в то время как вы повторяете строку за строкой. Поэтому, если вы делаете это с помощью итераций, вы должны также ссылаться на определенную строку, например: final_df ['D'] [row] == 'Kg'
  • Другая проблема связана с методом итерации. Хотя ваш цикл повторялся 4 раза, но было бесполезно перебирать его с помощью iterrows(). Я предлагаю использовать длину и создать диапазон значений и использовать это как индекс (который вы можете увидеть в моем ответе ниже).
  • И последний вопрос скорее зависит от того, что вы пытались сделать; поэтому, если вы хотите конвертировать Kg и Liter в Gram и mL, то вы должны размножаться и не делиться.

Здесь код:

final_df = pd.DataFrame({'D': ['g', 'Kg', 'l', 'ml'],'F': [500, 1, 1, 1000]})

for row in range(len(list(final_df.iterrows()))):
    if final_df['D'][row]=='Kg' or final_df['D'][row]=='l':
        final_df['F'][row]=final_df['F'][row]*1000

print(final_df)

Результат:

    D     F
0   g   500
1  Kg  1000
2   l  1000
3  ml  1000
  • 0
    Спасибо, что поправили меня. Я отредактировал проблему с конверсией :)
  • 0
    Есть больше способов сделать то же самое. Можно использовать .apply (), а внутри вы можете использовать лямбда-функции или пользовательскую функцию, и они изменяют значения в зависимости от условия. Я считаю, что это также может быть выполнено с использованием .where () и несколькими другими способами. Но это было бы слишком для такого случая. Но проверить это @dheerajkhanna
Показать ещё 1 комментарий
0

Использование -

df4['F'].astype(int).where( ~((df4['D']=='Kg') | (df4['D']=='l')),  df4['F'].astype(int)*1000)

Выход

0     500
1    1000
2    1000
3    1000
Name: F, dtype: int64

Ещё вопросы

Сообщество Overcoder
Наверх
Меню