Как заменить значения при загрузке данных с genfromtxt - PullRequest
1 голос
/ 01 июля 2019

Интересно, как я могу заменить определенные значения при загрузке данных из данного (CSV) файла с несколькими столбцами, комбинируя как строки, так и числовые значения.

В следующем примере предположим, что у вас есть несколько географических положений с известными широтами и долготами и определенным набором свойств (P1-P5) и классом (просто для включения строкового компонента задачи). Есть некоторые пропущенные значения, которые должным образом заменены на genfromtxt (в данном случае пропущенное значение равно -999), а также есть значения, которые не являются правильными (поддельные или другие типы флагов), такие как 0.0 , Как мы можем заменить 0,0 до -999?

Данные:

Name,lat,long,P1,P2,P3,P4,P5,Class
id1,71.234,10.123,0.0,11,212,222,1920,A
id2,72.234,11.111,,,312,342,1920,A
id3,77.832,12.111,1,0.0,,333,4520,B
id4,77.987,12.345,3,0.0,,231,2020,B
id5,77.111,13.099,5,11,212,222,1920,A

И код пока:

dfile = "data.csv"
missing_value = -999

import numpy as np

data = np.genfromtxt(dfile, unpack=True, comments='#', names=True, 
                    autostrip='Yes', filling_values=missing_value,
                    dtype=('S5', 'float', 'float', 'float', 'float', 'float', 'float', 'S1')
                    , delimiter=',',
                    )
new_data = np.where(data!=0.0 ,data, -999)

Я использовал np.where (data! = 0.0, data, -999), но я получил ошибку: TypeError: invalid type promotion

Я не знаю, что мне не хватает ...

ps 1. Возможно, это решаемо с Pandas, но я ищу независимое решение

ps 2. Я знаю, что грязным обходным решением было бы установить неправильные значения (0,0 с) как мой отсутствующий флаг в исходном файле, но что есть несколько значений, которые мы хотели бы исключить? (или объединение данных с разными флагами)

Ответы [ 2 ]

1 голос
/ 01 июля 2019

Определить простой текст:

In [55]: txt= '''foo,bar,test 
    ...: a,1,2 
    ...: b,3,4 
    ...: ''' 

загрузить с genfromtxt:

In [60]: data = np.genfromtxt(txt.splitlines(), encoding=None, names=True, dtype=None, delimiter=',')           
In [61]: data                                                                                                   
Out[61]: 
array([('a', 1, 2), ('b', 3, 4)],
      dtype=[('foo', '<U1'), ('bar', '<i8'), ('test', '<i8')])

Обратите внимание на dtype - поля с разными dtype и именами.

Доступполя по имени:

In [64]: data['foo']                                                                                            
Out[64]: array(['a', 'b'], dtype='<U1')

Изменить одно поле по индексу:

In [65]: data['bar']                                                                                            
Out[65]: array([1, 3])
In [66]: data['bar'][0] = 23                                                                                    

Изменить другое с помощью логического теста (или where):

In [67]: test = data['test']                                                                                    
In [68]: test                                                                                                   
Out[68]: array([2, 4])
In [69]: test==2                                                                                                
Out[69]: array([ True, False])
In [70]: test[test==2]=0                                                                                        
In [71]: test                                                                                                   
Out[71]: array([0, 4])
In [72]: data                                                                                                   
Out[72]: 
array([('a', 23, 0), ('b',  3, 4)],
      dtype=[('foo', '<U1'), ('bar', '<i8'), ('test', '<i8')])

Заменаможет быть проще, если вы сгруппировали числовые поля в одно (но это требует большего понимания dtypes структурированного массива):

In [80]: data = np.genfromtxt(txt.splitlines(), encoding=None, skip_header=1, dtype=[('id','U3'),('foo',int,2)],
    ...:  delimiter=',')                                                                                        
In [81]: data                                                                                                   
Out[81]: 
array([('a', [1, 2]), ('b', [3, 4])],
      dtype=[('id', '<U3'), ('foo', '<i8', (2,))])
In [82]: data['foo']                                                                                            
Out[82]: 
array([[1, 2],
       [3, 4]])
0 голосов
/ 01 июля 2019

Мне кажется, проблема в части np.genfromtxt. Создает пустой массив в форме:

np.array([np.void, np.void ... ])

Что приводит к сбою np.where. Один из способов обойти это:

data = np.array([[i for i in j] for j in data])

Я не думаю, что это очень хорошее решение. Но это должно работать, пока кто-то не придет с реальным ответом.

...