Преобразование серии Pandas, содержащей строку, в логическое значение

У меня есть DataFrame с именем df как

  Order Number       Status
1         1668  Undelivered
2        19771  Undelivered
3    100032108  Undelivered
4         2229    Delivered
5        00056  Undelivered

Я хотел бы преобразовать столбец Status в логическое значение (True, когда статус «Доставлено» и False, когда статус «Не доставлен»), но если статус не является ни «Не доставлен», ни «Доставлен», его следует рассматривать как NotANumber или что-то в этом роде.

Я хотел бы использовать дикт

d = {
  'Delivered': True,
  'Undelivered': False
}

поэтому я мог легко добавить другую строку, которую можно было бы рассматривать как True или False.


person working4coins    schedule 17.07.2013    source источник


Ответы (4)


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

In [7]: df = pd.DataFrame({'Status':['Delivered', 'Delivered', 'Undelivered',
                                     'SomethingElse']})

In [8]: df
Out[8]:
          Status
0      Delivered
1      Delivered
2    Undelivered
3  SomethingElse

In [9]: d = {'Delivered': True, 'Undelivered': False}

In [10]: df['Status'].map(d)
Out[10]:
0     True
1     True
2    False
3      NaN
Name: Status, dtype: object
person joris    schedule 17.07.2013
comment
я получаю AttributeError: 'DataFrame' object has no attribute 'map'. - person 7H3 IN5ID3R; 03.09.2017
comment
map — это метод Series, а не DataFrame. - person joris; 11.09.2017
comment
да понял, извини за это. - person 7H3 IN5ID3R; 11.09.2017

Пример метода replace для замены значений только в указанном столбце C2 и получения результата типа DataFrame.

import pandas as pd
df = pd.DataFrame({'C1':['X', 'Y', 'X', 'Y'], 'C2':['Y', 'Y', 'X', 'X']})

  C1 C2
0  X  Y
1  Y  Y
2  X  X
3  Y  X

df.replace({'C2': {'X': True, 'Y': False}})

  C1     C2
0  X  False
1  Y  False
2  X   True
3  Y   True
person Kappa Leonis    schedule 18.03.2017
comment
Хотя этот код может дать ответ на вопрос, предоставление дополнительного контекста относительно того, как и/или почему он решает проблему, улучшит долгосрочную ценность ответа. - person Donald Duck; 18.03.2017

У вас есть все, что вам нужно. Вы будете рады узнать replace:

df.replace(d)
person Dan Allan    schedule 17.07.2013
comment
Ах, я вижу это только сейчас, когда опубликовал свой ответ. Есть ли в этом случае разница с map? - person joris; 17.07.2013
comment
Вроде что-то другое (не в дифте) просто оставлено с replace, а преобразовано в NaN с map - person joris; 17.07.2013
comment
Я думаю, что map на самом деле здесь лучший выбор, потому что если значение не находится в d, то значение недействительно и должно быть заменено на NaN. - person Dan Allan; 17.07.2013
comment
replace, похоже, относится к DataFrame, а не к серии - person working4coins; 17.07.2013
comment
Это относится к обоим. Моя ссылка была на документацию DataFrame; вот один для серии. pandas.pydata.org/pandas-docs/dev/ сгенерировано/ - person Dan Allan; 17.07.2013

Расширение предыдущих ответов:

Объяснение метода карты:

  • Pandas будет искать значение каждой строки в соответствующем словаре d, заменяя все найденные ключи значениями из d.
  • Значения без ключей в d будут установлены как NaN. Это можно исправить с помощью fillna() способов.
  • Не работает с несколькими столбцами, так как pandas работает через сериализацию pd.Series здесь.
  • Документация: pd.Series.map
d = {'Delivered': True, 'Undelivered': False}
df["Status"].map(d)

Объяснение метода замены:

  • Pandas будет искать значение каждой строки в соответствующем словаре d и и пытаться заменить любые найденные ключи значениями из d.
  • Значения без ключей в d будут сохранены.
  • Работает с одним и несколькими столбцами (объекты pd.Series или pd.DataFrame).
  • Документация: pd.DataFrame.replace
d = {'Delivered': True, 'Undelivered': False}
df["Status"].replace(d)

В целом, метод замены более надежен и позволяет лучше контролировать способ сопоставления данных, а также способы обработки отсутствующих или незначащих значений.

person Yaakov Bressler    schedule 10.05.2020