如何在pandas中获取dataframe的分片
我从csv文件加载一些机器学习数据。 前两列是观察值,其余列是特征。
目前,我做了以下几点:
data = pandas.read_csv('mydata.csv')
这给了一些像:
data = pandas.DataFrame(np.random.rand(10,5), columns = list('abcde'))
我想在两个数据框中分割这个dataframe:一个包含列a
和b
,另一个包含列c
, d
和e
。
写这样的东西是不可能的
observations = data[:'c'] features = data['c':]
我不确定最好的方法是什么。 我需要一个pd.Panel
吗?
顺便说一下,我发现dataframe索引相当不一致: data['a']
是允许的,但data[0]
不是。 另一方面, data['a':]
是不允许的,但data[0:]
是。 这有没有一个实际的理由? 假如data[0] != data[0:1]
2017答案 – pandas 0.20:.ix已被弃用。 使用.loc
请参阅文档中的弃用
.loc
使用基于标签的索引来select行和列。 标签是索引或列的值。 用.loc
切片包括最后一个元素。
假设我们有一个包含以下列的DataFrame:
foo
,bar
,quz
,ant
,cat
,sat
,dat
。
# selects all rows and all columns beginning at 'foo' up to and including 'ant' 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
DataFrame.ix索引是你想要访问的。 这有点令人困惑(我同意pandas索引有时令人困惑!),但下面的内容似乎是做你想做的事情:
>>> df = DataFrame(np.random.rand(4,5), columns = list('abcde')) >>> df.ix[:,'b':] bcde 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 [行切片,列切片]是正在解释的内容。 更多关于pandas的索引: http : //pandas.pydata.org/pandas-docs/stable/indexing.html#indexing-advanced
让我们以seaborn包中的泰坦尼克数据集为例
# 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
>> titanic.ix[:,['sex','age','fare']]
要么
>> titanic.ix[:,[2,3,6]]
使用reindex方法
>> titanic.reindex(columns=['sex','age','fare'])
另外,给定一个DataFrame
数据
就像在你的例子中一样,如果你只想提取第一列和第四列(即第一列和第四列),pandas数据框中的iloc方法就是你需要的,可以非常有效地使用。 所有你需要知道的是你想要提取的列索引。 例如:
>>> data.iloc[:,[0,3]]
会给你
ad 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
您可以通过引用列表中每列的名称来切片DataFrame
的列,如下所示:
data = pandas.DataFrame(np.random.rand(10,5), columns = list('abcde')) data_ab = data[list('ab')] data_cde = data[list('cde')]
如果你来这里寻找切分两列的范围,并将它们组合在一起(像我一样),你可以做类似的事情
op = df[list(df.columns[0:899]) + list(df.columns[3593:])] print op
这将创build一个新的数据框,前900列和(所有)列> 3593(假设您的数据集中有大约4000列)。
以下是如何使用不同的方法来进行select性的列分割, 包括基于select性标签,基于索引和基于select性范围的列分割。
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]: abcdefg 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]: abc 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]: abc 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]: abc 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]: abc 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