Фильтрация данных в массивах и сохранение одинаковой формы на оси 1 - PullRequest
0 голосов
/ 04 марта 2020

Я пытаюсь получить некоторые специфические c значения для данного кадра данных, используя pandas и numpy.

Мой процесс сейчас выглядит следующим образом:

В [1]: df = pd.read_csv (файл)

В [2]: a = df [df.columns [1]]. Значения

Прямо сейчас a имеет следующую форму:

In [3]: a.shape

Out [4]: ​​(8640, 1)

Когда я фильтрую чтобы получить значения, соответствующие заданному условию, я не получаю одинаковую форму на оси 1:

В [5]: b = a [a> 100]

In [6]: b.shape

Out [7]: (3834,)

Прямо сейчас я изменяю новые массивы каждый раз, когда фильтрую их, однако это делает мой код действительно грязным и неудобным:

в [8]: (b.reshape (b.size, 1)). shape

Out [9]: ( 3834, 1)

Мне действительно нужно, чтобы он имел форму (x, 1), чтобы использовать некоторые другие функции, поэтому есть ли способ получить эту форму каждый раз, когда я отфильтровываю значения без необходимость постоянно изменять его?

РЕДАКТИРОВАТЬ:

Основная причина, по которой мне нужно сделать это изменение формы, заключается в том, что мне нужно получить минимальное значение в каждой строке для двух массивов с одинаковым количеством строк , Я использую np.min и np.concatenate. Например: av - это среднее значение 5 разных столбцов в моем фрейме данных:

av = np.mean (myColumns, axis = 1)

Который имеет форму (8640 ,) med - это медиана для тех же столбцов:

med = np.median (myColumns, axis = 1)

И когда я пытаюсь получить минимальные значения У меня следующая ошибка:

np.min (np.concatenate ((av, med), axis = 1), axis = 1) Traceback (последний вызов был последним):

Файл "", строка 1, в np.min (np.concatenate ((av, med), axis = 1), axis = 1)

AxisError: ось 1 выходит за границы массива размерность 1

Однако, если я изменить форму av и med, она будет работать нормально:

np.min (np.concatenate ((av.reshape (av.size, 1 ), med.reshape (av.size, 1)), axis = 1), axis = 1) Out [232]: array ([0., 0., 0., ..., 0., 0., 0.])

Ответы [ 3 ]

0 голосов
/ 04 марта 2020

Если вам действительно нужна эта форма, этот код дает форму (..., 1), и это не , что некрасиво:

np.expand_dims(a, 1)

или

a[:, np.newaxis]
0 голосов
/ 04 марта 2020

Если ваш код не слишком тяжелый, чтобы вы могли использовать numpy для повышения производительности, вы можете придерживаться pandas объектов (DataFrame / Series) и поддерживать форму.

Например, возьмите этот пример df (который, я должен добавить, вы должны были предоставить с вашим вопросом):

df = pd.DataFrame(data=np.random.rand(7,3), columns=['a','b','c'])
df
    a           b           c
0   0.382530    0.748674    0.186446
1   0.142991    0.965972    0.299884
2   0.568910    0.469341    0.896786
3   0.452816    0.021598    0.989637
4   0.884955    0.738519    0.082460
5   0.944797    0.103953    0.287005
6   0.379389    0.593280    0.832720

Чтобы создать объект с формой (7,1), вы можете использовать x = df[['a']], который представляет собой фрейм данных с одним столбцом (сравните с x=df['a'], который является серией с формой (7,)).

Теперь, если я перейду к массиву numpy с помощью y=x.values, я все равно получу ту же самую форму (оба x и y имеют формы (7,1)).

Однако оба по-разному реагируют на логическое индексирование: вызов y[y>0.3] вернет массив с формой (6,), тогда как вызов x[x>0.3] вернет. .. датафрейм с формой (7,1). Давайте посмотрим:

массив:

y[y>0.3]
array([0.38252971, 0.56890993, 0.45281553, 0.88495521, 0.94479716,
       0.37938899])

dataframe:

x[x>0.3]
    a
0   0.382530
1   NaN
2   0.568910
3   0.452816
4   0.884955
5   0.944797
6   0.379389

Итак, чтобы получить серию с нужной вам формой (6,1), вы можно использовать

x[x['a']>0.3]

, который возвращает

    a
0   0.382530
2   0.568910
3   0.452816
4   0.884955
5   0.944797
6   0.379389

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

Теперь, вообще говоря, манипуляции с массивами выполняются быстрее, чем с pandas объектами, но работать с pandas объектами проще, особенно если у вас много обработки данных.
Вы можете предпочесть работать с numpy полностью, но параметр pandas стоит знать, и, на мой взгляд, все проще и проще.

Надеюсь, это поможет!

0 голосов
/ 04 марта 2020

вы можете использовать np.take(a, np.where(a>100)[0], axis=0) для сохранения той же формы, что и оригинал

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