Как взять столбцы-срезы данных в pandas
Я загружаю некоторые данные машинного обучения из файла CSV. Первые 2 столбца являются наблюдениями, а остальные столбцы - объектами.
В настоящее время я делаю следующее:
data = pandas.read_csv('mydata.csv')
который дает что-то вроде:
data = pandas.DataFrame(np.random.rand(10,5), columns = list('abcde'))
Я хотел бы разделить этот фрейм данных на два фрейма: один, содержащий столбцы a
и b
и другой, содержащий столбцы c
, d
и e
.
Не возможно написать что-то вроде
observations = data[:'c']
features = data['c':]
Я не уверен, что лучший метод. Нужна ли мне pd.Panel
?
Между прочим, я нахожу, что индексирование по фрейму данных довольно противоречиво: data['a']
разрешены, а data[0]
- нет. С другой стороны, data['a':]
не разрешены, но data[0:]
разрешены. Есть ли практическая причина для этого? Это действительно сбивает с толку, если столбцы индексируются Int, учитывая, что data[0] != data[0:1]
Ответы
Ответ 1
Ответ 2017 - панды 0,20:.ix устарела. Используйте .loc
Смотрите амортизацию в документах
.loc
использует индексирование на основе меток для выбора строк и столбцов. Метки - это значения индекса или столбцов. Нарезка с помощью .loc
включает в себя последний элемент.
Предположим, у нас есть DataFrame со следующими столбцами:
foo
, bar
, quz
, ant
, cat
, sat
, dat
.
# selects all rows and all columns beginning at 'foo' up to and including 'sat'
df.loc[:, 'foo':'sat']
# foo bar quz ant cat sat
.loc
принимает ту же запись слайса, что и списки Python для строк и столбцов. Запись среза start:stop:step
# slice from 'foo' to 'cat' by every 2nd column
df.loc[:, 'foo':'cat':2]
# foo quz cat
# slice from the beginning to 'bar'
df.loc[:, :'bar']
# foo bar
# slice from 'quz' to the end by 3
df.loc[:, 'quz'::3]
# quz sat
# attempt from 'sat' to 'bar'
df.loc[:, 'sat':'bar']
# no columns returned
# slice from 'sat' to 'bar'
df.loc[:, 'sat':'bar':-1]
sat cat ant quz bar
# slice notation is syntatic sugar for the slice function
# slice from 'quz' to the end by 2 with slice function
df.loc[:, slice('quz',None, 2)]
# quz cat dat
# select specific columns with a list
# select columns foo, bar and dat
df.loc[:, ['foo','bar','dat']]
# foo bar dat
Вы можете нарезать по строкам и столбцам. Например, если у вас есть 5 строк с метками v
, w
, x
, y
, z
# slice from 'w' to 'y' and 'foo' to 'ant' by 3
df.loc['w':'y', 'foo':'ant':3]
# foo ant
# w
# x
# y
Ответ 2
Индекс DataFrame.ix - это то, к чему вы хотите получить доступ. Это немного сбивает с толку (я согласен, что индексирование Pandas иногда вызывает недоумение!), Но следующее, кажется, делает то, что вы хотите:
>>> df = DataFrame(np.random.rand(4,5), columns = list('abcde'))
>>> df.ix[:,'b':]
b c d e
0 0.418762 0.042369 0.869203 0.972314
1 0.991058 0.510228 0.594784 0.534366
2 0.407472 0.259811 0.396664 0.894202
3 0.726168 0.139531 0.324932 0.906575
где .ix [срез строки, срез столбца] - это то, что интерпретируется. Подробнее об индексации панд здесь: http://pandas.pydata.org/pandas-docs/stable/indexing.html#indexing-advanced
Примечание: .ix
устарела с Pandas v0.20. Вместо этого вы должны использовать .loc
или .iloc
, в зависимости от ситуации.
Ответ 3
Давайте использовать в качестве примера титановый набор данных из пакета морского происхождения
# Load dataset (pip install seaborn)
>> import seaborn.apionly as sns
>> titanic = sns.load_dataset('titanic')
используя имена столбцов
>> titanic.loc[:,['sex','age','fare']]
используя индексы столбцов
>> titanic.iloc[:,[2,3,6]]
используя ix (старше Pandas <.20 версия)
>> titanic.ix[:,[‘sex,age,fare]]
или же
>> titanic.ix[:,[2,3,6]]
используя метод переиндексации
>> titanic.reindex(columns=['sex','age','fare'])
Ответ 4
Также, учитывая DataFrame
данные
как в вашем примере, если вы хотите извлечь только столбцы a и d (например, 1-й и 4-й столбцы), iloc mothod из фреймворка pandas - это то, что вам нужно, и может быть использовано очень эффективно. Все, что вам нужно знать, это индекс столбцов, которые вы хотите извлечь. Например:
>>> data.iloc[:,[0,3]]
предоставит вам
a d
0 0.883283 0.100975
1 0.614313 0.221731
2 0.438963 0.224361
3 0.466078 0.703347
4 0.955285 0.114033
5 0.268443 0.416996
6 0.613241 0.327548
7 0.370784 0.359159
8 0.692708 0.659410
9 0.806624 0.875476
Ответ 5
Вы можете обрезать столбцы DataFrame
, ссылаясь на имена каждого столбца в списке, например:
data = pandas.DataFrame(np.random.rand(10,5), columns = list('abcde'))
data_ab = data[list('ab')]
data_cde = data[list('cde')]
Ответ 6
И если вы пришли сюда, чтобы нарезать два диапазона столбцов и объединить их вместе (как и я), вы можете сделать что-то вроде
op = df[list(df.columns[0:899]) + list(df.columns[3593:])]
print op
Это создаст новый фреймворк с первыми 900 столбцами и (всеми) столбцами > 3593 (при условии, что в вашем наборе данных имеется около 4000 столбцов).
Ответ 7
Здесь вы можете использовать различные методы для выборочной сортировки столбцов, , включая выборочную наклейку, основанную на индексах и разделение столбцов на основе выборочных диапазонов.
In [37]: import pandas as pd
In [38]: import numpy as np
In [43]: df = pd.DataFrame(np.random.rand(4,7), columns = list('abcdefg'))
In [44]: df
Out[44]:
a b c d e f g
0 0.409038 0.745497 0.890767 0.945890 0.014655 0.458070 0.786633
1 0.570642 0.181552 0.794599 0.036340 0.907011 0.655237 0.735268
2 0.568440 0.501638 0.186635 0.441445 0.703312 0.187447 0.604305
3 0.679125 0.642817 0.697628 0.391686 0.698381 0.936899 0.101806
In [45]: df.loc[:, ["a", "b", "c"]] ## label based selective column slicing
Out[45]:
a b c
0 0.409038 0.745497 0.890767
1 0.570642 0.181552 0.794599
2 0.568440 0.501638 0.186635
3 0.679125 0.642817 0.697628
In [46]: df.loc[:, "a":"c"] ## label based column ranges slicing
Out[46]:
a b c
0 0.409038 0.745497 0.890767
1 0.570642 0.181552 0.794599
2 0.568440 0.501638 0.186635
3 0.679125 0.642817 0.697628
In [47]: df.iloc[:, 0:3] ## index based column ranges slicing
Out[47]:
a b c
0 0.409038 0.745497 0.890767
1 0.570642 0.181552 0.794599
2 0.568440 0.501638 0.186635
3 0.679125 0.642817 0.697628
### with 2 different column ranges, index based slicing:
In [49]: df[df.columns[0:1].tolist() + df.columns[1:3].tolist()]
Out[49]:
a b c
0 0.409038 0.745497 0.890767
1 0.570642 0.181552 0.794599
2 0.568440 0.501638 0.186635
3 0.679125 0.642817 0.697628
Ответ 8
Его эквивалент
>>> print(df2.loc[140:160,['Relevance','Title']])
>>> print(df2.ix[140:160,[3,7]])
Ответ 9
если фрейм данных выглядит так:
group name count
fruit apple 90
fruit banana 150
fruit orange 130
vegetable broccoli 80
vegetable kale 70
vegetable lettuce 125
и ВЫХОД может быть как
group name count
0 fruit apple 90
1 fruit banana 150
2 fruit orange 130
если вы используете логический оператор np.logical_not
df[np.logical_not(df['group'] == 'vegetable')]
больше о
https://docs.scipy.org/doc/numpy-1.13.0/reference/routines.logic.html
другие логические операторы
-
logic_and (x1, x2,/[, out, where,...]) Вычисляет значение истинности x1 И x2 поэлементно.
-
logic_or (x1, x2,/[, out, where, casting,...]) Вычислить значение истинности x1 ИЛИ x2 поэлементно.
- logic_not (x,/[, out, where, casting,...]) Вычисляет значение истинности NOT x поэлементно.
- logic_xor (x1, x2,/[, out, where,..]) Вычисляет значение истинности x1 XOR x2 поэлементно.
Ответ 10
Другой способ получить подмножество столбцов из вашего DataFrame, предполагая, что вы хотите, чтобы все строки были следующими:
data[['a','b']]
и data[['c','d','e']]
Если вы хотите использовать числовые индексы столбцов, вы можете сделать:
data[data.columns[:2]]
и data[data.columns[2:]]