Как бы я векторизовал функцию в pandas, которая возвращает список? - PullRequest
0 голосов
/ 19 февраля 2020

Я читал о , как оптимизировать pandas код для скорости , и я пытаюсь реорганизовать мой код, переключившись с iterrows() на векторизацию. Вот пример старого кода и его результата:

Старый код

import pandas as pd
def repeatAsList(value):
    return([value, value])
df = pd.DataFrame({"values": [1,2,3], "repeatedAsList":None})
for index, row in df.iterrows():
    df.at[index,"repeatedAsList"] = repeatAsList(row['values'])
df

Старый результат

+--------+----------------+
| values | repeatedAsList |
+--------+----------------+
|      1 | [1, 1]         |
|      2 | [2, 2]         |
|      3 | [3, 3]         |
+--------+----------------+

Новый код

import pandas as pd
def repeatAsList(value):
    return([value, value])
df = pd.DataFrame({"values": [1,2,3], "repeatedAsList":None})
df["repeatedAsList"] = repeatAsList(df["values"])

Новый результат

ValueError: Length of values does not match length of index

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

Ответы [ 3 ]

1 голос
/ 19 февраля 2020

Я считаю, что вы можете сделать это быстрее, создав массив с использованием значений:

df['repeatedAsList'] = [[x,x] for x in (df['values'].values)]
print(df)

Вывод:

  values repeatedAsList
0       1         [1, 1]
1       2         [2, 2]
2       3         [3, 3]

Относительно скорости:

Здесь вы можете увидеть скорость для больших кадров данных и получить к ним доступ с помощью values, tolist() и некоторых других функций. Я полагаю, что самый быстрый способ получить доступ к значениям - .values для больших наборов данных (более 100 строк): ошибка при получении значения при попытке создания вспомогательных участков для списка данных с помощью matplotlib?

                        1      10     100    1000   10000
len 1               0.0038  0.0046  0.0032  0.0037  0.0035
len 10              0.0032  0.0032  0.0032  0.0034  0.0035
len 100             0.0032  0.0052  0.0052  0.0053  0.0035
len 1000            0.0037  0.0036  0.0041  0.0039  0.0043
len 10000           0.0040  0.0038  0.0045  0.0043  0.0123
len(tolist) 1       0.0051  0.0075  0.0175  0.1629  1.6579
len(tolist) 10      0.0051  0.0059  0.0175  0.1588  1.9253
len(tolist) 100     0.0049  0.0097  0.0196  0.1635  1.7422
len(tolist) 1000    0.0053  0.0065  0.0198  0.1831  1.9897
len(tolist) 10000   0.0057  0.0069  0.0218  0.1995  2.2426
len(values) 1       0.0083  0.0097  0.0073  0.0074  0.0074
len(values) 10      0.0073  0.0072  0.0073  0.0107  0.0087
len(values) 100     0.0075  0.0094  0.0109  0.0072  0.0081
len(values) 1000    0.0081  0.0082  0.0081  0.0085  0.0088
len(values) 10000   0.0087  0.0084  0.0103  0.0101  0.0327
shape   1           0.1108  0.0838  0.0789  0.0779  0.0780
shape   10          0.0764  0.0770  0.0771  0.1118  0.0806
shape   100         0.0952  0.0826  0.1013  0.0800  0.0889
shape   1000        0.0881  0.0863  0.0867  0.0938  0.1063
shape   10000       0.0905  0.0999  0.1043  0.1013  0.2384
0 голосов
/ 19 февраля 2020

Вы можете попробовать map:

df['repeatedAsList'] = list(map(lambda x: [x,x], df['values'].values))
#df['repeatedAsList'] = list(map(lambda x: [x,x], df['values']) #seems slow


   values repeatedAsList 
0       1         [1, 1] 
1       2         [2, 2] 
2       3         [3, 3] 
0 голосов
/ 19 февраля 2020

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

df['repeated_column'] = [[item, item] for item in df['values'].to_list()]

Пожалуйста, проверьте и дайте мне знать.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...