Наиболее эффективный способ обработки списка списков массивов разной длины в python - PullRequest
0 голосов
/ 16 июня 2020

У меня есть словарь, содержащий списки значений разной длины. Мне нужно иметь возможность обрабатывать все значения в определенном индексе (столбце) в каждом списке вместе. Единственный способ, который я нашел, - это преобразовать его в фрейм данных pandas. Однако это очень медленно для фактического набора данных, который может включать 1000+ событий (строк) с сотнями наблюдений (столбцов) на событие.

Упрощенный пример будет выглядеть примерно так:

event_dict= {}
event_dict['event1'] = [1,2,3,4,5]
event_dict['event2'] = [1,3,5,4,7,8,9,8]
event_dict['event3'] = [1,3,2,4]
event_dict['event4'] = [1, -1, 1, 2, 2,5]
#actual dictionary can have thousand+ rows with 100+ entries per row

event_df = pd.DataFrame()
for key in event_dict:
    temp_df = pd.DataFrame(event_dict[key])
    event_df = event_df.append(temp_df, ignore_index = True)

print(values_df)
values_df.mean()

Результат будет примерно таким:

   0  1  2  3    4    5    6    7
0  1  2  3  4  5.0  NaN  NaN  NaN
1  1  3  5  4  7.0  8.0  9.0  8.0
2  1  3  2  4  NaN  NaN  NaN  NaN
3  1 -1  1  2  2.0  5.0  NaN  NaN

0    1.000000
1    1.750000
2    2.750000
3    3.500000
4    4.666667
5    6.500000
6    9.000000
7    8.000000

Поскольку каждый список содержит разное количество значений, мне трудно найти эффективную реализацию, которая не использует фреймы данных. Фактический код занимает больше всего времени на создание самого values_df, учитывая количество необходимых итераций et c. Когда у меня есть фрейм данных, я могу векторизовать его, но до этого я застреваю.

1 Ответ

4 голосов
/ 16 июня 2020

Используйте DataFrame.from_dict и параметр orient='index':

s = pd.DataFrame.from_dict(event_dict, orient='index').mean()
print (s)
0    1.000000
1    1.750000
2    2.750000
3    3.500000
4    4.666667
5    6.500000
6    9.000000
7    8.000000
dtype: float64

Другой вариант - использовать zip_longest с заполнением пропущенных значений для разной длины:

from  itertools import zip_longest

a = np.nanmean(np.array(list(zip_longest(*list(event_dict.values()), fillvalue=np.nan))), 
               axis=1)
print (a)
[1.         1.75       2.75       3.5        4.66666667 6.5
 9.         8.        ]

s = pd.Series(a)
print (s)
0    1.000000
1    1.750000
2    2.750000
3    3.500000
4    4.666667
5    6.500000
6    9.000000
7    8.000000
dtype: float64
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...