Ответ 1
Итак, термин трансляция происходит от numpy, просто объясните правила вывода, которые будут возникать при выполнении операций между n -мерные массивы (могут быть панели, dataframes, series) или скалярные значения.
Вещание с использованием скалярного значения
Итак, простейший случай просто умножается на скалярное значение:
In [4]:
s = pd.Series(np.arange(5))
s
Out[4]:
0 0
1 1
2 2
3 3
4 4
dtype: int32
In [5]:
s * 10
Out[5]:
0 0
1 10
2 20
3 30
4 40
dtype: int32
и мы получаем те же ожидаемые результаты с помощью блока данных:
In [6]:
df = pd.DataFrame({'a':np.random.randn(4), 'b':np.random.randn(4)})
df
Out[6]:
a b
0 0.216920 0.652193
1 0.968969 0.033369
2 0.637784 0.856836
3 -2.303556 0.426238
In [7]:
df * 10
Out[7]:
a b
0 2.169204 6.521925
1 9.689690 0.333695
2 6.377839 8.568362
3 -23.035557 4.262381
Итак, что технически происходит здесь, так это то, что скалярное значение транслировалось по тем же размерам, что и Series и DataFrame выше.
Вещание с использованием 1-мерного массива
Предположим, что у нас есть двухмерная форма данных формы 4 x 3 (4 строки x 3 столбца), мы можем выполнить операцию вдоль оси x, используя 1-D-серию, которая имеет такую же длину, как длина строки
In [8]:
df = pd.DataFrame({'a':np.random.randn(4), 'b':np.random.randn(4), 'c':np.random.randn(4)})
df
Out[8]:
a b c
0 0.122073 -1.178127 -1.531254
1 0.011346 -0.747583 -1.967079
2 -0.019716 -0.235676 1.419547
3 0.215847 1.112350 0.659432
In [26]:
df.iloc[0]
Out[26]:
a 0.122073
b -1.178127
c -1.531254
Name: 0, dtype: float64
In [27]:
df + df.iloc[0]
Out[27]:
a b c
0 0.244146 -2.356254 -3.062507
1 0.133419 -1.925710 -3.498333
2 0.102357 -1.413803 -0.111707
3 0.337920 -0.065777 -0.871822
выше выглядит смешно сначала, пока вы не поймете, что происходит, я взял первую строку значений и добавил эту строку в df, ее можно визуализировать с помощью этого рисунка (из scipy
):
Общее правило таково:
Для трансляции размер задних осей для обоих массивов в операции должен быть либо одного размера, либо один из них должен быть один.
Итак, если я попытался добавить массив с 1-D, который не совпал по длине, скажем, что один из 4 элементов, в отличие от numpy, который поднимет ValueError
, в Pandas вы получите df, полный NaN
значения:
In [30]:
df + pd.Series(np.arange(4))
Out[30]:
a b c 0 1 2 3
0 NaN NaN NaN NaN NaN NaN NaN
1 NaN NaN NaN NaN NaN NaN NaN
2 NaN NaN NaN NaN NaN NaN NaN
3 NaN NaN NaN NaN NaN NaN NaN
Теперь некоторые из великих вещей о Pandas состоят в том, что он попытается выровнять с использованием существующих имен столбцов и ярлыков строк, это может помешать попыткам более удобного вещания следующим образом:
In [55]:
df[['a']] + df.iloc[0]
Out[55]:
a b c
0 0.244146 NaN NaN
1 0.133419 NaN NaN
2 0.102357 NaN NaN
3 0.337920 NaN NaN
В приведенном выше примере я использую двойную подпитку, чтобы заставить фигуру быть (4,1), но мы видим проблему при попытке трансляции с использованием первой строки, поскольку выравнивание столбцов выравнивается только в первом столбце. Чтобы получить такую же форму вещания, как показано на диаграмме выше, мы должны разложить на массивы numpy, которые затем становятся анонимными:
In [56]:
df[['a']].values + df.iloc[0].values
Out[56]:
array([[ 0.24414608, -1.05605392, -1.4091805 ],
[ 0.13341899, -1.166781 , -1.51990758],
[ 0.10235701, -1.19784299, -1.55096957],
[ 0.33792013, -0.96227987, -1.31540645]])
Также возможно транслировать в 3-мерных измерениях, но я часто не приближаюсь к этому материалу, но в книге numpy, scipy и Pandas есть примеры, показывающие, как это работает.
Вообще говоря, важно помнить, что помимо простых скалярных значений для массивов n-D длина младших/конечных осей должна совпадать или одна из них должна быть 1.