Ich lade einige maschinelle Lerndaten aus einer CSV-Datei. Die ersten 2 Spalten sind Beobachtungen und die verbleibenden Spalten sind Merkmale.
Derzeit mache ich Folgendes:
data = pandas.read_csv('mydata.csv')
was gibt so etwas wie:
data = pandas.DataFrame(np.random.Rand(10,5), columns = list('abcde'))
Ich möchte dieses Datenframe in zwei Datenframes schneiden: Eines enthält die Spalten a
und b
und eines enthält die Spalten c
, d
und e
.
Es ist nicht möglich etwas zu schreiben
observations = data[:'c']
features = data['c':]
Ich bin nicht sicher, was die beste Methode ist. Benötige ich einen pd.Panel
?
Übrigens finde ich die Datenfeldindizierung ziemlich inkonsistent: data['a']
ist erlaubt, aber data[0]
nicht. Auf der anderen Seite ist data['a':]
nicht erlaubt, aber data[0:]
ist . Gibt es einen praktischen Grund dafür? Dies ist wirklich verwirrend, wenn Spalten von Int indexiert werden, da data[0] != data[0:1]
Siehe deprecation in den Dokumenten .
.loc
verwendet die auf Etiketten basierende Indexierung, um sowohl Zeilen als auch Spalten auszuwählen. Die Bezeichnungen sind die Werte des Index oder der Spalten. Das Schneiden mit .loc
enthält das letzte Element.
Nehmen wir an, wir haben einen DataFrame mit den folgenden Spalten:
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
akzeptiert dieselbe Slice-Notation, die Python-Listen sowohl für Zeilen als auch für Spalten verwenden. Slice-Notation ist 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
Sie können nach Zeilen und Spalten schneiden. Wenn Sie beispielsweise 5 Zeilen mit den Beschriftungen v
, w
, x
, y
, z
haben
# slice from 'w' to 'y' and 'foo' to 'ant' by 3
df.loc['w':'y', 'foo':'ant':3]
# foo ant
# w
# x
# y
Auf den DataFrame.ix-Index möchten Sie zugreifen. Es ist ein wenig verwirrend (ich bin damit einverstanden, dass die Indexierung von Pandas manchmal verwirrend ist!), Aber das Folgende scheint zu tun, was Sie wollen:
>>> 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
dabei wird .ix [Zeilenschnitt, Spaltenschnitt] interpretiert. Mehr zur Pandas-Indexierung hier: http://pandas.pydata.org/pandas-docs/stable/indexing.html#indexing-advanced
Hinweis:.ix
wurde seit Pandas v0.20 nicht mehr unterstützt. Verwenden Sie stattdessen .loc
oder .iloc
.
Verwenden wir als Beispiel den titanischen Datensatz aus dem Seaborn-Paket
# Load dataset (pip install seaborn)
>> import seaborn.apionly as sns
>> titanic = sns.load_dataset('titanic')
mit den Spaltennamen
>> titanic.loc[:,['sex','age','fare']]
unter Verwendung der Spaltenindizes
>> titanic.iloc[:,[2,3,6]]
mit ix (älter als Pandas <.20-Version)
>> titanic.ix[:,[‘sex’,’age’,’fare’]]
oder
>> titanic.ix[:,[2,3,6]]
mit der reindex-Methode
>> titanic.reindex(columns=['sex','age','fare'])
Auch ein DataFrame gegeben
daten
wenn Sie wie in Ihrem Beispiel nur die Spalten a und d (z. B. die 1. und 4. Spalte) extrahieren möchten, ist iloc mothod aus dem Pandas-Datenrahmen genau das, was Sie brauchen und sehr effektiv eingesetzt werden können. Alles, was Sie wissen müssen, ist der Index der Spalten, die Sie extrahieren möchten. Zum Beispiel:
>>> data.iloc[:,[0,3]]
werde dir geben
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
Sie können sich entlang der Spalten einer DataFrame
aufteilen, indem Sie auf die Namen jeder Spalte in einer Liste verweisen.
data = pandas.DataFrame(np.random.Rand(10,5), columns = list('abcde'))
data_ab = data[list('ab')]
data_cde = data[list('cde')]
Und wenn Sie hierher gekommen sind, um zwei Spaltenbereiche zu schneiden und sie (wie ich) zu kombinieren, können Sie so etwas tun
op = df[list(df.columns[0:899]) + list(df.columns[3593:])]
print op
Dadurch wird ein neuer Datenrahmen mit den ersten 900 Spalten und (allen) Spalten> 3593 erstellt (vorausgesetzt, Sie haben etwa 4000 Spalten in Ihrem Datensatz).
So können Sie verschiedene Methoden verwenden, um selektives Spalten-Slicing durchzuführen: einschließlich selektives Label-basiertes, indexbasiertes und selektives Spalten-Slicing
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
Sein Äquivalent
>>> print(df2.loc[140:160,['Relevance','Title']])
>>> print(df2.ix[140:160,[3,7]])
Eine andere Möglichkeit zum Abrufen einer Teilmenge von Spalten aus Ihrem DataFrame, vorausgesetzt, Sie möchten alle Zeilen, besteht darin, Folgendes zu tun:data[['a','b']]
und data[['c','d','e']]
Wenn Sie numerische Spaltenindizes verwenden möchten, haben Sie folgende Möglichkeiten:data[data.columns[:2]]
und data[data.columns[2:]]
wenn der Datenrahmen so aussieht:
group name count
fruit Apple 90
fruit banana 150
fruit orange 130
vegetable broccoli 80
vegetable kale 70
vegetable lettuce 125
und OUTPUT könnte so sein
group name count
0 fruit Apple 90
1 fruit banana 150
2 fruit orange 130
wenn Sie den logischen Operator np.logical_not verwenden
df[np.logical_not(df['group'] == 'vegetable')]
mehr über
https://docs.scipy.org/doc/numpy-1.13.0/reference/routines.logic.html
andere logische Operatoren
logisch_und (x1, x2,/[ out, where, ...]) Berechnen Sie den Wahrheitswert von x1 UND x2 elementweise.
logic_or (x1, x2,/[ out, where, casting, ...]) Berechnen Sie den Wahrheitswert von x1 OR x2 elementweise.