Как складывать массивы разных форм? Создайте 3d-массив из нескольких 2d-массивов разной длины - PullRequest
0 голосов
/ 25 апреля 2020

Некоторый контекст

Код, используемый для чтения данных из нескольких файлов и их размещения в стек для формирования списка двумерных массивов, имитирующих numpy stacking:

import glob
import pandas as pd
import numpy as np

def read_file(files):
    data = []
    for i in range( len(files) ):
                try:   
                    ehists.append( pd.read_csv(files[i], delimiter = "\t", compression='gzip', header=None).to_numpy() )
                except pd.errors.EmptyDataError:
                    pass
    return data


foldername = "datafolder"

### reading files with names file1, file2.......
files = glob.glob("./"+foldername+"/file*")

3dData = read_file(files)


Основной запрос

Для простоты предположим, что каждый файл имеет 3 столбца, но имеет разную длину (количество строк). Столбец 1 представляет время, столбцы 2 и 3 - некоторые точки данных в то время. Итак, типичный файл выглядит примерно так:

10    0.34    1.37
15    0.39    1.42
20    0.45    1.47
25    0.57    1.53
30    0.68    1.62
35    0.82    1.89
40    0.92    1.97

Чтобы построить гистограмму распределения значений столбца 2 из всех файлов в разное время, я анализирую список массивов, используя следующий код:

import matplotlib.pyplot as plt

t_end = 1000
t = np.arange(0, t_end, 1)

y = []

for time in t:
    y_t = []
    for i in range( len(3dData) ):           ## iterating over files(2d-arrays)
        for j in range( np.shape(3dData[i])[0] ):  ## iterating over rows in the 2d-array
            if 3dData[i][j,0] == time:
                y_t.append( 3dData[i][j,1] )
    y.append( y_t )

## Hist of values at t=10
t0 = 10
plt.hist(y[t0])
plt.show()

То, чего я хочу достичь, - это работа для меня. Однако, поскольку у меня в списке ~ 100000 2d-массивов, приведенный выше код выполняется довольно долго. Я чувствую, что несогласованность типов объектов приводит к более медленной обработке при анализе данных. (Правильно ли я так считаю, и) Есть ли способ складировать 2d-массивы различной формы без необходимости дополнять данные 2-мерного массива?

PS: я могу предоставить больше информации, если это необходимо, и я буду очень рад получить советы / предложения о том, как сделать этот код более эффективным.

Спасибо за ваше время и энергия!

1 Ответ

1 голос
/ 25 апреля 2020

Вероятно, есть лучшие способы сделать это. numpy вероятно будет более производительным для манипулирования массивами.

Но вот один из способов нормализовать длину списка списков с помощью zip_longest(). Это повлечет за собой итерацию по всему набору данных, поскольку элементы списка проходят через два уровня итераторов zip.

>>> from itertools import zip_longest
>>>
>>> rows = [[random.randint(100, 999) 
...          for _ in range(random.randint(5, 10))] 
...         for _ in range(10)]
...
>>> for row in rows:
...     print(row)
...     
[826, 735, 223, 394, 885, 122, 259, 899, 788, 121]
[984, 405, 185, 984, 727, 901, 704, 526, 936]
[617, 814, 801, 382, 138, 245, 225]
[314, 478, 103, 509, 559, 687, 124, 869, 596]
[982, 741, 714, 489, 613, 392, 940, 577, 155]
[752, 262, 365, 213, 451, 925, 610]
[555, 288, 277, 975, 573]
[507, 753, 537, 721, 629]
[235, 971, 970, 721, 571]
[367, 627, 335, 955, 410, 393, 387, 935, 793]
>>> 
>>> padded_rows = [list(row) for row in zip(*zip_longest(*rows, fillvalue='#'))]
>>> for row in padded_rows:
...     print(row)
...     
[826, 735, 223, 394, 885, 122, 259, 899, 788, 121]
[984, 405, 185, 984, 727, 901, 704, 526, 936, '#']
[617, 814, 801, 382, 138, 245, 225, '#', '#', '#']
[314, 478, 103, 509, 559, 687, 124, 869, 596, '#']
[982, 741, 714, 489, 613, 392, 940, 577, 155, '#']
[752, 262, 365, 213, 451, 925, 610, '#', '#', '#']
[555, 288, 277, 975, 573, '#', '#', '#', '#', '#']
[507, 753, 537, 721, 629, '#', '#', '#', '#', '#']
[235, 971, 970, 721, 571, '#', '#', '#', '#', '#']
[367, 627, 335, 955, 410, 393, 387, 935, 793, '#']
>>> 

Не уверен, что означает подделка данных. Этот подход просто копирует ссылки на данные из списка в список, поэтому он не выполняет никаких операций над самими данными.

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