Слишком медленная повторная выборка и интерполяция панд - PullRequest
0 голосов
/ 30 августа 2018

У меня есть сценарий использования, в котором я повторно выбираю небольшой фрейм данных, созданный из списка из 10 объектов JSON. В фрейме данных 10 строк по 50 столбцов с 20% пропущенных полей. После повторной выборки я интерполирую столбец данных столбец за столбцом, так как я должен выбрать метод интерполяции, определенный пользователем. Код для этого выглядит следующим образом:

df = pd.DataFrame(packets_dict)
df = df.set_index('datetime')
df = df.resample('60S').first()
for column in columns_rule:
    if column in df.columns:
        # replace value by null if it is out of given min and max values.
        if 'max_value' in columns_rule[column].keys():
            df[column] = df[column].where(df[column] < columns_rule['column']['max_value'])
        if 'min_value' in columns_rule[column].keys():
            df[column] = df[column].where(df[column] > column_rule[column]['min_value'])
        df[column] = df[column].interpolate(method=linear, limit=3)

Мне нужно запустить этот код при потоковой передаче данных с высокой скоростью. Но этот код занимает слишком много времени для выполнения. Я сделал профилирование этого кода, который показывает следующие результаты, выполнив этот код 990 раз.

повторная выборка занимает 137,347 секунды и вызывается 990 раз, 138,79 мс для одного вызова функции.

, где 75.272 занимает секунды и вызывается 87120 раз, 0,864 мс для одного вызова функции.

интерполировать занимает 21,928 секунд и вызывается 43560 раз, 0,503 мс для одного вызова функции.

Остальная часть кода довольно быстрая и не занимает много времени. Общее время, затрачиваемое этими функциями на прохождение 990 итераций, составляет 234,5 секунды, что составляет почти 4 минуты, что намного превышает нашу требуемую скорость. Мне нужно оптимизировать этот код, чтобы сократить время в 20–30 раз. Есть ли способ, которым я могу оптимизировать эти функции панд, или, может быть, я делаю что-то не так, используя эти функции.

Я использую Pandas 0.23.0 с python3.

Я искал его, но не смог найти никакого решения. Пожалуйста, помогите мне с вашими комментариями и предложениями.

Вот пример данных, если кто-то хочет попробовать: Это не фактические данные, так как они не могут быть разделены, но данные, которые я предоставляю, очень сильно зависят от числа чисел с плавающей запятой, целых чисел и, кроме того, от количества столбцов и строк. Более того, для строковых столбцов я использую ffill или bfill, а не функцию интерполяции.

packets_dict = [
{'datetime':"2018-08-01 22:05:40",'field1':12.4,'field2':'aab','field3':1234,'field4':12.4,'field5':'aab','field6':1234,'field7':12.4,'field8':'aab','field9':1234,'field10':12.4,'field11':'aab','field12':1234,'field13':12.4,'field14':'aab','field15':1234,'field16':12.4,'field17':'aab','field18':1234,'field19':12.4,'field20':'aab','field21':1234,'field22':12.4,'field23':'aab','field24':1234,'field25':12.4,'field26':'aab','field27':1234,'field28':12.4,'field29':'aab','field30':1234,'field31':12.4,'field32':'aab','field33':1234,'field34':12.4,'field35':'aab','field36':1234,'field37':12.4,'field38':'aab','field39':1234,'field40':12.4,'field41':'aab','field42':1234,'field43':12.4,'field44':'aab','field45':1234,'field46':12.4,'field47':'aab','field48':1234,'field49':12.4},
{'datetime':"2018-08-01 22:06:41",'field10':12.4,'field11':'aab','field12':1234,'field13':12.4,'field14':'aab','field15':1234,'field16':12.4,'field17':'aab','field18':1234,'field19':12.4,'field20':'aab','field21':1234,'field22':12.4,'field23':'aab','field24':1234,'field25':12.4,'field26':'aab','field27':1234,'field28':12.4,'field29':'aab','field30':1234,'field31':12.4,'field32':'aab','field33':1234,'field34':12.4,'field35':'aab','field36':1234,'field37':12.4,'field38':'aab','field39':1234,'field40':12.4,'field41':'aab','field42':1234,'field43':12.4,'field44':'aab','field45':1234,'field46':12.4,'field47':'aab','field48':1234,'field49':12.4},
{'datetime':"2018-08-01 22:07:42",'field1':12.4,'field2':'aab','field3':1234,'field4':12.4,'field5':'aab','field6':1234,'field7':12.4,'field8':'aab','field9':1234,'field10':12.4,'field11':'aab','field12':1234,'field13':12.4,'field14':'aab','field15':1234,'field16':12.4,'field17':'aab','field18':1234,'field19':12.4,'field20':'aab','field21':1234,'field22':12.4,'field23':'aab','field24':1234,'field25':12.4,'field26':'aab','field27':1234,'field28':12.4,'field29':'aab','field30':1234,'field31':12.4,'field32':'aab','field33':1234,'field34':12.4,'field35':'aab','field36':1234,'field37':12.4,'field38':'aab','field39':1234,'field40':12.4,'field41':'aab','field42':1234,'field43':12.4,'field44':'aab','field45':1234,'field46':12.4,'field47':'aab','field48':1234,'field49':12.4},
{'datetime':"2018-08-01 22:08:44",'field1':12.4,'field2':'aab','field3':1234,'field4':12.4,'field5':'aab','field6':1234,'field7':12.4,'field8':'aab','field21':1234,'field22':12.4,'field23':'aab','field24':1234,'field25':12.4,'field26':'aab','field27':1234,'field28':12.4,'field29':'aab','field30':1234,'field31':12.4,'field32':'aab','field33':1234,'field34':12.4,'field35':'aab','field36':1234,'field37':12.4,'field38':'aab','field39':1234,'field40':12.4,'field41':'aab','field42':1234,'field43':12.4,'field44':'aab','field45':1234,'field46':12.4,'field47':'aab','field48':1234,'field49':12.4},
{'datetime':"2018-08-01 22:09:46",'field1':12.4,'field2':'aab','field3':1234,'field4':12.4,'field5':'aab','field6':1234,'field7':12.4,'field8':'aab','field9':1234,'field10':12.4,'field11':'aab','field12':1234,'field13':12.4,'field14':'aab','field15':1234,'field16':12.4,'field17':'aab','field18':1234,'field25':12.4,'field26':'aab','field27':1234,'field28':12.4,'field29':'aab','field30':1234,'field31':12.4,'field32':'aab','field33':1234,'field34':12.4,'field35':'aab','field36':1234,'field37':12.4,'field38':'aab','field39':1234,'field40':12.4,'field41':'aab','field42':1234,'field43':12.4,'field44':'aab','field45':1234,'field46':12.4,'field47':'aab','field48':1234,'field49':12.4},
{'datetime':"2018-08-01 22:10:49",'field1':12.4,'field2':'aab','field3':1234,'field4':12.4,'field5':'aab','field6':1234,'field7':12.4,'field8':'aab','field9':1234,'field10':12.4,'field11':'aab','field12':1234,'field13':12.4,'field14':'aab','field15':1234,'field16':12.4,'field17':'aab','field18':1234,'field19':12.4,'field20':'aab','field21':1234,'field22':12.4,'field23':'aab','field24':1234,'field25':12.4,'field26':'aab','field27':1234,'field28':12.4,'field41':'aab','field42':1234,'field43':12.4,'field44':'aab','field45':1234,'field46':12.4,'field47':'aab','field48':1234,'field49':12.4},
{'datetime':"2018-08-01 22:11:50",'field1':12.4,'field2':'aab','field3':1234,'field4':12.4,'field5':'aab','field6':1234,'field7':12.4,'field8':'aab','field9':1234,'field10':12.4,'field11':'aab','field12':1234,'field13':12.4,'field14':'aab','field15':1234,'field16':12.4,'field17':'aab','field18':1234,'field19':12.4,'field20':'aab','field21':1234,'field22':12.4,'field23':'aab','field24':1234,'field25':12.4,'field26':'aab','field27':1234,'field28':12.4,'field29':'aab','field30':1234,'field31':12.4,'field32':'aab','field33':1234,'field34':12.4,'field35':'aab','field36':1234,'field37':12.4,'field48':1234,'field49':12.4},
{'datetime':"2018-08-01 22:12:54",'field1':12.4,'field2':'aab','field3':1234,'field4':12.4,'field5':'aab','field6':1234,'field7':12.4,'field8':'aab','field9':1234,'field10':12.4,'field11':'aab','field12':1234,'field13':12.4,'field14':'aab','field15':1234,'field16':12.4,'field17':'aab','field18':1234,'field19':12.4,'field20':'aab','field21':1234,'field22':12.4,'field23':'aab','field24':1234,'field25':12.4,'field26':'aab','field27':1234,'field28':12.4,'field38':'aab','field39':1234,'field40':12.4,'field41':'aab','field42':1234,'field43':12.4,'field44':'aab','field45':1234,'field46':12.4,'field47':'aab','field48':1234,'field49':12.4},
{'datetime':"2018-08-01 22:15:55",'field1':12.4,'field2':'aab','field3':1234,'field4':12.4,'field5':'aab','field6':1234,'field7':12.4,'field8':'aab','field9':1234,'field10':12.4,'field11':'aab','field12':1234,'field13':12.4,'field14':'aab','field15':1234,'field16':12.4,'field17':'aab','field18':1234,'field19':12.4,'field20':'aab','field21':1234,'field22':12.4,'field23':'aab','field24':1234,'field25':12.4,'field26':'aab','field27':1234,'field28':12.4,'field29':'aab','field30':1234,'field31':12.4,'field32':'aab','field33':1234,'field34':12.4,'field35':'aab','field36':1234,'field37':12.4,'field38':'aab','field39':1234,'field40':12.4,'field41':'aab','field42':1234,'field43':12.4,'field44':'aab','field45':1234,'field46':12.4,'field47':'aab','field48':1234,'field49':12.4},
{'datetime':"2018-08-01 22:16:01",'field1':12.4,'field2':'aab','field3':1234,'field4':12.4,'field5':'aab','field6':1234,'field7':12.4,'field8':'aab','field28':12.4,'field29':'aab','field30':1234,'field31':12.4,'field32':'aab','field33':1234,'field34':12.4,'field35':'aab','field36':1234,'field37':12.4,'field38':'aab','field39':1234,'field40':12.4,'field41':'aab','field42':1234,'field43':12.4,'field44':'aab','field45':1234,'field46':12.4,'field47':'aab','field48':1234,'field49':12.4}
]

columns_rule = {
'field1':{
    'max_value':999,
    'min_value':0
},
'field3':{
    'max_value':999,
    'min_value':0
},
'field4':{
    'max_value':999,
    'min_value':0
},
'field6':{
    'max_value':999,
    'min_value':0
},
'field7':{
    'max_value':999,
    'min_value':0
},
'field9':{
    'max_value':999,
    'min_value':0
},
'field10':{
    'max_value':999,
    'min_value':0
},
'field12':{
    'max_value':999,
    'min_value':0
},
'field13':{
    'max_value':999,
    'min_value':0
},
'field15':{
    'max_value':999,
    'min_value':0
},
'field16':{
    'max_value':999,
    'min_value':0
},
'field18':{
    'max_value':999,
    'min_value':0
},
'field19':{
    'max_value':999,
    'min_value':0
},
'field21':{
    'max_value':999,
    'min_value':0
},
'field22':{
    'max_value':999,
    'min_value':0
},
'field24':{
    'max_value':999,
    'min_value':0
},
'field25':{
    'max_value':999,
    'min_value':0
},
'field26':'aab',
'field27':{
    'max_value':999,
    'min_value':0
},
'field28':{
    'max_value':999,
    'min_value':0
},
'field30':{
    'max_value':999,
    'min_value':0
},
'field31':{
    'max_value':999,
    'min_value':0
},
'field33':{
    'max_value':999,
    'min_value':0
},
'field34':{
    'max_value':999,
    'min_value':0
},
'field36':{
    'max_value':999,
    'min_value':0
},
'field37':{
    'max_value':999,
    'min_value':0
},
'field39':{
    'max_value':999,
    'min_value':0
},
'field40':{
    'max_value':999,
    'min_value':0
},
'field42':{
    'max_value':999,
    'min_value':0
},
'field43':{
    'max_value':999,
    'min_value':0
},
'field45':{
    'max_value':999,
    'min_value':0
},
'field46':{
    'max_value':999,
    'min_value':0
},
'field48':{
    'max_value':999,
    'min_value':0
},
'field49':{
    'max_value':999,
    'min_value':0
}
}

1 Ответ

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

Идея состоит в том, чтобы извлечь значения dict в цикле, а затем работать с DataFrame всех сопоставленных столбцов, и вместо этого resample используется Grouper с groupby:

df = df.set_index('datetime').groupby(pd.Grouper(freq='60S')).first()

dmin, dmax = {}, {}
cmin, cmax = [],[]
for column in columns_rule:
    if column in df.columns:
        if 'max_value' in columns_rule[column]:
            dmax[column] = columns_rule[column]['max_value']
            cmax.append(column)
        if 'min_value' in columns_rule[column]:
            dmin[column] = columns_rule[column]['min_value']
            cmin.append(column)

m1 = df[cmax].lt(pd.Series(dmax))
m2 = df[cmin].gt(pd.Series(dmin))

cols = np.union1d(cmin, cmax)
df[cmax] = np.where(m1, df[cmax], np.nan)
df[cmin] = np.where(m2, df[cmin], np.nan)
df[cols] = df[cols].interpolate(method='linear', limit=3)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...