Как я могу разделить подвыборы фрейма данных на другой фрейм данных, используя минимальное использование памяти в Python? - PullRequest
0 голосов
/ 12 сентября 2018

У меня есть фрейм данных со многими столбцами, и я хочу разделить его на другой фрейм данных с регулярными интервалами столбцов с минимальным использованием памяти.

Например:

df1 = pd.DataFrame([[1,2,3,4,5,6,7,8,9,10], [10,9,8,7,6,5,4,3,2,1], [2,4,3,1,6,5,7,8,9,4]])
df2 = pd.DataFrame([[1,3],[7,6],[9,3]])

Я хочу разделить df1 на df2 несколько раз через каждые два столбца.Результат, который я хотел бы получить:

finalDf = pd.DataFrame([[1/1,2/3,3/1,4/3,5/1,6/3,7/1,8/3,9/1,10/3], [10/7,9/6,8/7,7/6,6/7,5/6,4/7,3/6,2/7,1/6], [2/9,4/3,3/9,1/3,6/9,5/3,7/9,8/3,9/9,4/3]])

Я думаю, что код будет выглядеть примерно так:

df3 = df1.iloc[:, 0:2].divide(df2.iloc[:,:].values, axis = 'rows')
df4 = df1.iloc[:, 2:4].divide(df2.iloc[:,:].values, axis = 'rows')
df5 = df1.iloc[:, 4:6].divide(df2.iloc[:,:].values, axis = 'rows')
df6 = df1.iloc[:, 6:8].divide(df2.iloc[:,:].values, axis = 'rows')
finalDf = pd.concat([df3, df4, df5, df6], axis=1)

Единственный способ, которым я могу подумать, реализовать что-то подобное, это поставитьэто в цикле, но я чувствую, что это не умный способ сделать это.Есть ли способ векторизации решения?

Ответы [ 3 ]

0 голосов
/ 12 сентября 2018

Предполагая, что столбцы являются числовыми, вы можете обмануть панд в выполнении индексированного выровненного деления, переназначая столбцы df1 для имитации df2.

df1.columns = np.tile(df2.columns, df1.shape[1] // df2.shape[1])
# A little more trickery to restore the ordering later.
ordering = df1.columns.values.argsort(kind='mergesort').argsort()

print (df1)
    0  1  0  1  0  1  0  1  0   1
0   1  2  3  4  5  6  7  8  9  10
1  10  9  8  7  6  5  4  3  2   1
2   2  4  3  1  6  5  7  8  9   4

print (df2)
   0  1
0  1  3
1  7  6
2  9  3

result = df1.div(df2).iloc[:, ordering]

Это не создает никаких дополнительных данных.

0 голосов
/ 12 сентября 2018

Все на месте

for c in df1:
  df1[c] /= df2[c % 2].values  # added .values to try and quicken it up a bit

df1.round(4)

        0       1       2       3       4       5       6       7       8       9
0  1.0000  0.6667  3.0000  1.3333  5.0000  2.0000  7.0000  2.6667  9.0000  3.3333
1  1.4286  1.5000  1.1429  1.1667  0.8571  0.8333  0.5714  0.5000  0.2857  0.1667
2  0.2222  1.3333  0.3333  0.3333  0.6667  1.6667  0.7778  2.6667  1.0000  1.3333

Независимо от имен столбцов

from itertools import cycle

for i, j in zip(df1, cycle(df2)):
  df1[i] /= df2[j].values

df1.round(4)

        0       1       2       3       4       5       6       7       8       9
0  1.0000  0.6667  3.0000  1.3333  5.0000  2.0000  7.0000  2.6667  9.0000  3.3333
1  1.4286  1.5000  1.1429  1.1667  0.8571  0.8333  0.5714  0.5000  0.2857  0.1667
2  0.2222  1.3333  0.3333  0.3333  0.6667  1.6667  0.7778  2.6667  1.0000  1.3333
0 голосов
/ 12 сентября 2018

Использование pd.concat:

res = pd.concat([df2]*5, 1)
res.columns = df1.columns

df1/res

          0         1         2         3    ...            6         7         8         9
0  1.000000  0.666667  3.000000  1.333333    ...     7.000000  2.666667  9.000000  3.333333
1  1.428571  1.500000  1.142857  1.166667    ...     0.571429  0.500000  0.285714  0.166667
2  0.222222  1.333333  0.333333  0.333333    ...     0.777778  2.666667  1.000000  1.333333

Для обобщения:

res = pd.concat([df2]*(df1.shape[1]//df2.shape[1]), 1)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...