Преобразование объекта в float с помощью pandas (python) [duplicate]

Большинство ответов здесь не могут объяснить, какова фактическая проблема с разрезанием. Они объясняют только доброкачественные случаи нарезки, а не предательские. Предположим, как и другие ответы, что вы имеете дело с двумя классами A и B, где B получает (публично) из A.

В этой ситуации C ++ позволяет вам передать экземпляр оператора B в A, а также в конструктор копирования. Это работает, потому что экземпляр B может быть преобразован в const A&, а именно, какие операторы присваивания и конструкторы-копии ожидают, что их аргументы будут.

Доброкачественный случай

B b;
A a = b;

Ничего плохого в этом нет - вы попросили экземпляр A, который является копией B, и это именно то, что вы получаете. Конечно, a не будет содержать некоторых членов b, но как это сделать? В конце концов, это A, а не B, поэтому даже не слышал об этих членах, не говоря уже о возможности их хранения.

вероломный случай

B b1;
B b2;
A& a_ref = b2;
a_ref = b1;
//b2 now contains a mixture of b1 and b2!

Вы можете подумать, что b2 будет копией b1 впоследствии. Но, увы, это не так! Если вы проверите его, вы обнаружите, что b2 - это франкенштейновское существо, сделанное из некоторых кусков b1 (куски, которые B наследует от A), и некоторые фрагменты b2 (куски что только B содержит). Ой!

Что случилось? Ну, C ++ по умолчанию не обрабатывает операторы присваивания как virtual. Таким образом, строка a_ref = b1 вызовет оператор присваивания A, а не номер B. Это связано с тем, что для не виртуальных функций объявленный тип (который является A&) определяет, какая функция вызывается, в отличие от фактического типа (который был бы B, поскольку a_ref ссылается на экземпляр B ). Теперь оператор присваивания A явно знает только о членах, объявленных в A, поэтому он будет копировать только те, оставляя члены, добавленные в B без изменений.

Решение

Присвоение только части объекта обычно имеет мало смысла, но, к сожалению, C ++ не предусматривает встроенного способа запретить это. Вы можете, однако, бросить свои собственные. Первый шаг - сделать оператор присваивания виртуальным . Это гарантирует, что он всегда является оператором присваивания фактического типа, который вызывается, а не объявленным типом. Второй шаг - использовать dynamic_cast, чтобы убедиться, что назначенный объект имеет совместимый тип. Третий шаг - выполнить фактическое присвоение в члене (protected!) assign(), так как B assign(), вероятно, захочет использовать A 's assign() для копирования A членов .

class A {
public:
  virtual A& operator= (const A& a) {
    assign(a);
    return *this;
  }

protected:
  void assign(const A& a) {
    // copy members of A from a to this
  }
};

class B : public A {
public:
  virtual B& operator= (const A& a) {
    if (const B* b = dynamic_cast<const B*>(&a))
      assign(*b);
    else
      throw bad_assignment();
    return *this;
  }

protected:
  void assign(const B& b) {
    A::assign(b); // Let A's assign() copy members of A from b to this
    // copy members of B from b to this
  }
};

Обратите внимание, что для чистого удобства B operator= ковариантно переопределяет возвращаемый тип, поскольку он знает, что он возвращает экземпляр B.

25
задан Amelio Vazquez-Reina 25 August 2013 в 23:04
поделиться

4 ответа

В pandas 0.17.0 convert_objects вызывают предупреждение:

FutureWarning: convert_objects устарел. Используйте специальные преобразователи данных типа pd.to_datetime, pd.to_timedelta и pd.to_numeric.

Вы можете использовать метод pd.to_numeric и применить его для кадра данных с arg coerce.

df1 = df.apply(pd.to_numeric, args=('coerce',))

или может быть более подходящим образом:

df1 = df.apply(pd.to_numeric, errors='coerce')

EDIT

Этот метод действителен только для версии pandas> = 0.17.0, from docs Что нового в pandas 0.17.0 :

pd.to_numeric - это новая функция, которая может принуждать строки к числам (возможно, с принуждением) (GH11133)

43
ответ дан Cleb 21 August 2018 в 17:08
поделиться
  • 1
    Пальцы, пересекшие это, вернулись, это была отличная серебряная пуля. – Andy Hayden 20 November 2015 в 07:44
  • 2
    Объект 'module' не имеет атрибута 'to_numeric'? – bgenchel 30 November 2015 в 08:27
  • 3
    показать отредактированную версию, она доступна только из 0.17.0 версии pandas – Anton Protopopov 30 November 2015 в 08:44

Вы можете просто использовать pd.to_numeric и установить ошибку на coerce без использования apply

df['foo'] = pd.to_numeric(df['foo'], errors='coerce')
4
ответ дан Amirhos Imani 21 August 2018 в 17:08
поделиться

Используйте метод серии convert_objects convert_numeric):

In [11]: s
Out[11]: 
0    103.8
1    751.1
2      0.0
3      0.0
4        -
5        -
6      0.0
7        -
8      0.0
dtype: object

In [12]: s.convert_objects(convert_numeric=True)
Out[12]: 
0    103.8
1    751.1
2      0.0
3      0.0
4      NaN
5      NaN
6      0.0
7      NaN
8      0.0
dtype: float64

Примечание: это также доступно как метод DataFrame.

31
ответ дан Andy Hayden 21 August 2018 в 17:08
поделиться
  • 1
    "Попытка вывести лучший dtype для столбцов объекта" это в основном волшебная пуля ... (и это тоже относится к датам). – Andy Hayden 25 August 2013 в 23:41
  • 2
    Спасибо!!! этот метод должен быть в каждом уроке pandas. – delgadom 9 October 2015 в 19:34
  • 3
    @delgadom suprisingly не существует «очистки», в учебнике 10 минут . Мне нужно закончить свою книгу :) – Andy Hayden 9 October 2015 в 22:17
  • 4
    К сожалению, он обесценился: / – Newskooler 31 January 2018 в 15:43

Сначала замените все строковые значения на None, чтобы пометить их как отсутствующие значения, а затем преобразовать их в float.

df['foo'][df['foo'] == '-'] = None
df['foo'] = df['foo'].astype(float)
7
ответ дан Viktor Kerkez 21 August 2018 в 17:08
поделиться
  • 1
    Благодаря! Хорошо и просто. – Amelio Vazquez-Reina 25 August 2013 в 23:24
  • 2
    Простой и работает намного лучше, чем предыдущие предложения. – Gunay Anach 9 August 2017 в 13:04
  • 3
    это не работает для меня ... любая идея? – ngakak 14 September 2017 в 08:32
Другие вопросы по тегам:

Похожие вопросы: