2016-05-29 6 views
3

У меня есть файл CSV. Большинство его значений я хочу читать как строку, но я хочу прочитать столбец как bool, если существует столбец с данным заголовком.Pandas read_csv dtype указать все столбцы, кроме одного

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

data = read_csv('sample.csv', dtype={'A': str, 'B': str, ..., 'X': bool}) 

можно ли определить тип строки на каждой колонке, но один и прочитать дополнительный столбец как BOOL в то же время?

Мое текущее решение заключается в следующем (но это очень unefficient и медленно):

data = read_csv('sample.csv', dtype=str) # reads all column as string 
if 'X' in data.columns: 
    l = lambda row: True if row['X'] == 'True' else False if row['X'] == 'False' else None 
    data['X'] = data.apply(l, axis=1) 

UPDATE: Образец CSV:

A;B;C;X 
a1;b1;c1;True 
a2;b2;c2;False 
a3;b3;c3;True 

Или же можно ба без столбца 'X' (поскольку колонка не является обязательной):

A;B;C 
a1;b1;c1 
a2;b2;c2 
a3;b3;c3 

ответ

2

Вы можете сначала фильтровать столбцы contains значение X с boolean indexing, а затем replace:

cols = df.columns[df.columns.str.contains('X')] 
df[cols] = df[cols].replace({'True': True, 'False': False}) 

Или, если колонка необходимости фильтр X:

cols = df.columns[df.columns == 'X'] 
df[cols] = df[cols].replace({'True': True, 'False': False}) 

Образец:

import pandas as pd 

df = pd.DataFrame({'A':['a1','a2','a3'], 
        'B':['b1','b2','b3'], 
        'C':['c1','c2','c3'], 
        'X':['True','False','True']}) 

print (df) 
    A B C  X 
0 a1 b1 c1 True 
1 a2 b2 c2 False 
2 a3 b3 c3 True 
print (df.dtypes) 
A object 
B object 
C object 
X object 
dtype: object 

cols = df.columns[df.columns.str.contains('X')] 
print (cols) 

Index(['X'], dtype='object') 

df[cols] = df[cols].replace({'True': True, 'False': False}) 

print (df.dtypes) 
A object 
B object 
C object 
X  bool 
dtype: object 
print (df) 

    A B C  X 
0 a1 b1 c1 True 
1 a2 b2 c2 False 
2 a3 b3 c3 True 
+0

Спасибо! Это намного быстрее, чем мое решение! – user1802693

+0

Это решение имеет очень большую проблему. Оно устанавливает значения False в значения True. Любая строка с нулевой длиной анализируется как True. – user1802693

+1

Вы абсолютно правы, поэтому я редактирую ответ. – jezrael

1

почему н ot использование bool() данные type. bool() не будет истинным, если передается параметр и параметр не является ложным, None, «», или 0

if 'X' in data.columns: 
    try: 
     l = bool(data.columns['X'].replace('False', 0)) 
    except: 
     l = None 
    data['X'] = data.apply(l, axis=1) 
+0

Я думаю, что применение выражения лямбда замедляет время обработки. – user1802693

+1

Да, определенно. Если бы я собирался подойти к нему так, как вы это делали, тогда я бы использовал оператор if/else. 'if data == 'False': l = False' 'elif data == 'True': l = True'' else: l = None', но я бы использовал ответы, которые были предоставлены. Предполагая, что у вас большой набор данных, я бы воспользовался обоими решениями и использовал самые быстрые решения. Удачи – TheLazyScripter

1

На самом деле вам не нужно никакого специального обращения при использовании read_csv из панд (проверено на версии 0.17) , Использование вашего файла примера с помощью X:

import pandas as pd 

df = pd.read_csv("file.csv", delimiter=";") 
print(df.dtypes) 

A object 
B object 
C object 
X  bool 
dtype: object 
+0

Мне это не нужно по умолчанию, но мои данные очень особенные (это сочетание буквенно-цифровых чисел). Это одна из причин, почему у меня есть это ограничение для некоторых столбцов, чтобы сохранить специальные числовые числа в строчном формате. – user1802693

Смежные вопросы