Присвоение фрейму данных не работает, но изменены dtypes

#python #pandas

#python #pandas

Вопрос:

Присвоение фрейму данных не работает, но изменены dtypes.

Новичок в науке о данных, я хочу присвоить target_frame empty_frame , но это не работает, пока не назначит снова. И во время присвоений dtypes of empty_frame изменилось с int32 на float64 и, наконец, настроено на int64 .

Я пытаюсь упростить свою модель, как показано в приведенном ниже коде, у них та же проблема.

 import pandas as pd
import numpy as np

dataset = [[[i for i in range(5)], ] for i in range(5)]
dataset = pd.DataFrame(dataset, columns=['test'])  

empty_numpy = np.arange(25).reshape(5, 5)
empty_numpy.fill(np.nan)

# Solution 1: change the below code into 'empty_frame = pd.DataFrame(empty_numpy)' then everything will be fine
empty_frame = pd.DataFrame(empty_numpy, columns=[str(i) for i in range(5)])

series = dataset['test']
target_frame = pd.DataFrame(list(series))

# Solution 2: run `empty_frame[:] = target_frame` twice, work fine to me.
# ==================================================================
# First try.
empty_frame[:] = target_frame
print("="*40)
print(f"Data types of empty_frame: {empty_frame.dtypes}")
print("="*40)

print("Result of first try: ")
print(empty_frame)
print("="*40)


# Second try.
empty_frame[:] = target_frame

print(f"Data types of empty_frame: {empty_frame.dtypes}")
print("="*40)

print("Result of second try: ")
print(empty_frame)
print("="*40)
# ====================================================================
  

Я ожидаю, что вывод кода выше должен быть:

 ========================================
Data types of empty_frame: 0    int64
1    int64
2    int64
3    int64
4    int64
dtype: object
========================================
Result of first try: 
   0  1  2  3  4
0  0  1  2  3  4
1  0  1  2  3  4
2  0  1  2  3  4
3  0  1  2  3  4
4  0  1  2  3  4
========================================
  

но это не работает при первой попытке.

Есть два решения этой проблемы, но я не знаю, почему:

  • как я показал в своем коде, попробуйте присвоение дважды за один запуск.
  • удалите имена столбцов при создании empty_frame .

Две вещи, которые я хочу выяснить:

  1. почему empty_frame изменились типы данных.
  2. почему решения, показанные в моем коде, могут решить эту проблему с присвоением.

Спасибо.

Ответ №1:

если я правильно понимаю ваш вопрос, то ваша проблема начинается при создании матрицы empty_numpy. Моим любимым решением было бы использовать empty_numpy = np.empty([5,5]) вместо этого (dtypes по умолчанию здесь float64). Тогда «Результат первой попытки:» является правильным. Это означает:

 import pandas as pd
import numpy as np

dataset = [[[i for i in range(5)],] for i in range(5)]
dataset = pd.DataFrame(dataset, columns=['test'])  

empty_numpy = np.empty([5,5])
# here you may add empty_numpy.fill(np.nan) but it's not necessary,result is the same

empty_frame = pd.DataFrame(empty_numpy, columns=[str(i) for i in range(5)])

series = dataset['test']
target_frame = pd.DataFrame(list(series))

# following assignment is correct then
empty_frame[:] = target_frame
print('='*40)
print(f'Data types of empty_frame: {empty_frame.dtypes}')
print('='*40)

print("Result of first try: ")
print(empty_frame)
print("="*40)
  

Или просто добавьте атрибут dtype к вашему вызову np.arrange, точно так же, как это:

 empty_numpy = np.arange(25, dtype=float).reshape(5, 5)
  

Тогда это тоже работает (но это немного скучно; o).

Комментарии:

1. Спасибо за ваше решение. насколько я понимаю, это потому, что тип np.nan is float64 , который не выполнил задание. Но меня все еще что-то смущает, почему один и тот же код выводит разные данные. Как вы можете видеть, я запускаю эту строку empty_frame[:] = target_frame дважды в моем примере, но получил другой результат, для меня это неразумно, чтобы иметь смысл.

2. @KayCrazy, dtype вашего target_frame int64 , но dtype empty_frame в вашем решении — int32 . Первое присвоение empty_frame[:] = target_frame просто преобразует empty_frame в float64 — в противном случае вы можете потерять точность (когда target_frame будет содержать значения> диапазона int32 ). Второй запуск уже присваивает значения (потому что float64 > int64 ). Вы можете избежать этой проблемы, если явно зададите dtype в функции np.arrange или используете np.empty (там по умолчанию используется значение float). Достаточно ли этого объяснения?