I load a some machine learning data from a csv file. The first 2 columns are observations and the remaining columns are features.
Currently, I do the following :
data = pandas.read_csv('mydata.csv')
which gives something like:
data = pandas.DataFrame(np.random.rand(10,5), columns = list('abcde'))
I'd like to slice this dataframe in two dataframes: one containing the columns a and b and one containing the columns c, d and e.
It is not possible to write something like
observations = data[:'c'] features = data['c':]
I'm not sure what the best method is. Do I need a pd.Panel?
By the way, I find dataframe indexing pretty inconsistent: data['a'] is permitted, but data[0] is not. On the other side, data['a':] is not permitted but data[0:] is. Is there a practical reason for this? This is really confusing if columns are indexed by Int, given that data[0] != data[0:1]
回答1:
2017 Answer - pandas 0.20: .ix is deprecated. Use .loc
.loc uses label based indexing to select both rows and columns. The labels being the values of the index or the columns. Slicing with .loc includes the last element.
Let's assume we have a DataFrame with the following columns: 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 accepts the same slice notation that Python lists do for both row and columns. Slice notation being 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
You can slice by rows and columns. For instance, if you have 5 rows with labels 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:
The DataFrame.ix index is what you want to be accessing. It's a little confusing (I agree that Pandas indexing is perplexing at times!), but the following seems to do what you want:
>>> df =DataFrame(np.random.rand(4,5), columns = list('abcde'))>>> df.ix[:,'b':] b c d e 00.4187620.0423690.8692030.97231410.9910580.5102280.5947840.53436620.4074720.2598110.3966640.89420230.7261680.1395310.3249320.906575
as in your example, if you would like to extract column a and d only (e.i. the 1st and the 4th column), iloc mothod from the pandas dataframe is what you need and could be used very effectively. All you need to know is the index of the columns you would like to extract. For example:
>>> data.iloc[:,[0,3]]
will give you
a d 00.8832830.10097510.6143130.22173120.4389630.22436130.4660780.70334740.9552850.11403350.2684430.41699660.6132410.32754870.3707840.35915980.6927080.65941090.8066240.875476
回答5:
You can slice along the columns of a DataFrame by referring to the names of each column in a list, like so:
And if you came here looking for slicing two ranges of columns and combining them together (like me) you can do something like
op = df[list(df.columns[0:899])+ list(df.columns[3593:])]print op
This will create a new dataframe with first 900 columns and (all) columns > 3593 (assuming you have some 4000 columns in your data set).
回答7:
Here's how you could use different methods to do selective column slicing, including selective label based, index based and the selective ranges based column 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 00.4090380.7454970.8907670.9458900.0146550.4580700.78663310.5706420.1815520.7945990.0363400.9070110.6552370.73526820.5684400.5016380.1866350.4414450.7033120.1874470.60430530.6791250.6428170.6976280.3916860.6983810.9368990.101806In[45]: df.loc[:,["a","b","c"]]## label based selective column slicing Out[45]: a b c 00.4090380.7454970.89076710.5706420.1815520.79459920.5684400.5016380.18663530.6791250.6428170.697628In[46]: df.loc[:,"a":"c"]## label based column ranges slicing Out[46]: a b c 00.4090380.7454970.89076710.5706420.1815520.79459920.5684400.5016380.18663530.6791250.6428170.697628In[47]: df.iloc[:,0:3]## index based column ranges slicing Out[47]: a b c 00.4090380.7454970.89076710.5706420.1815520.79459920.5684400.5016380.18663530.6791250.6428170.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 00.4090380.7454970.89076710.5706420.1815520.79459920.5684400.5016380.18663530.6791250.6428170.697628