Ответ 1
Виновником являются неустранимые показатели
Ваши индексы DataFrames различны (и, соответственно, индексы для каждого столбца), поэтому при попытке назначить столбец одного DataFrame другому, pandas будет пытаться выровнять индексы, и, если это не удастся, вставить NaN.
Рассмотрим следующие примеры, чтобы понять, что это значит:
# Setup
A = pd.DataFrame(index=['a', 'b', 'c'])
B = pd.DataFrame(index=['b', 'c', 'd', 'f'])
C = pd.DataFrame(index=[1, 2, 3])
# Example of alignable indexes - A & B (complete or partial overlap of indexes)
A.index B.index
a
b b (overlap)
c c (overlap)
d
f
# Example of unalignable indexes - A & C (no overlap at all)
A.index C.index
a
b
c
1
2
3
Если перекрытий нет, панды не могут сопоставить даже одно значение между двумя фреймами данных, чтобы вставить результат присваивания, поэтому на выходе получается столбец, заполненный NaN.
Если вы работаете над ноутбуком IPython, вы можете проверить, что это действительно основная причина, используя
df1.index.equals(df2.index)
# False
df1.index.intersection(df2.index).empty
# True
Для решения этой проблемы вы можете использовать любое из следующих решений.
Решение 1. Сброс обоих индексов DataFrames
Вы можете предпочесть эту опцию, если вы изначально не хотели иметь разные индексы или если вы не особенно заботитесь о сохранении индекса.
# Optional, if you want a RangeIndex => [0, 1, 2, ...]
# df1.index = pd.RangeIndex(len(df))
# Homogenize the index values,
df2.index = df1.index
# Assign the columns.
df2[['date', 'hour']] = df1[['date', 'hour']]
Если вы хотите сохранить существующий индекс, но в виде столбца, вы можете использовать reset_index()
.
Решение 2. Назначьте массивы NumPy (обход индекса по объему)
Это решение будет работать только в том случае, если длины двух фреймов данных совпадают.
# pandas >= 0.24
df2['date'] = df1['date'].to_numpy()
# pandas < 0.24
df2['date'] = df1['date'].values
Чтобы легко назначить несколько столбцов, используйте,
df2 = df2.assign(**{c: df1[c].to_numpy() for c in ('date', 'hour')})