[TOC]
Index对象是不可更改的(immutable)。index[1]=\'d\'就会出错。但是,df.index=index_new是可以的。
对于reindex可以修改(行)索引、列,或两个都修改。1frame.reindex(columns=states)重新索引列。
df.drop([list1,list2])默认是删除的指定的行,如果想要删除某一列,就需要df.drop([list1,list2],axis=1)。
自己的认识,axis是指查找数据的一个方向,axis=0是指查找数据时是竖直方向去找,axis=1是水平方向去找数据。这样,这里想要删除某一列,就需要是水平方向去找到该列名。否则,提示找不到。
Series索引,Series索引值不止是整数。
obj = Series(np.arange(4.), index=[\'a\', \'b\', \'c\', \'d\'])
obj[0]
obj[:2]    #找到:obj[0],obj[1]
obj[\'a\']
obj[[\'a\',\'c\']]
obj[\'a\':\'c\'] #找到:obj[0],obj[1],obj[2]  标签索引,闭区间!
以上索引方式都可以。
利用标签的切片运算和普通的Python切片运算是不同的,其末端是包含的(inclusive)。闭区间
对DataFrame索引其实就是获取一个或多个列。
data = DataFrame(np.arange(16).reshape((4, 4)),
                 index=[\'Ohio\', \'Colorado\', \'Utah\', \'New York\'],
                 columns=[\'one\', \'two\', \'three\', \'four\'])
data[\'two\']
data[[\'three\',\'one\']]
这时候,不能像Series那样直接选取行了,如:data[\'Ohio\']
那么,选择行怎么做呢?
# 这里举例选取前三行
data[:3] 选取了0,1,2行
# 或者
data.ix[\'Ohio\':\'Utah\',:]   
# 或者
data.ix[0:3]
# 或者
data.loc[\'Ohio\':\'Utah\',:]
# 或者
data.iloc[0:3,:] 
以上,后边的冒号可以省略。
ix标签索引,位置索引都可以
loc标签索引
iloc位置索引
再强调一遍,标签索引是闭区间!
布尔索引
data[data[\'three\']>5]
data[data<5]
data.ix[data.three>5,:3]
总结下来,ix索引最牛逼!灵活结合了标签索引和位置索引!
pandas最重要的一个功能是,它可以对不同索引的对象进行算数运算。
对于DataFrame,对齐操作将会同时发生在行和列上。
没有重叠的位置会产生NA值–NaN。
广播功能,需要注意索引,如果某个索引值在DataFrame或者Series的索引中找不到,则参与运算就会容易形成NA值。
如果希望匹配行且在列上广播,则必须使用算术运算方法。例如:
series3 = frame[\'d\']
frame.sub(series3, axis=0)

结果:
| b | d | e | |
|---|---|---|---|
| Utah | -1.0 | 0.0 | 1.0 | 
| Ohio | -1.0 | 0.0 | 1.0 | 
| Texas | -1.0 | 0.0 | 1.0 | 
| Oregon | -1.0 | 0.0 | 1.0 | 
元素及的Python函数也是可以的。假如想得到frame中各个浮点值的格式化字符串,使用applymap函数。
frame = DataFrame(np.random.randn(4, 3), columns=list(\'bde\'),
                  index=[\'Utah\', \'Ohio\', \'Texas\', \'Oregon\'])
format = lambda x: \'%.2f\' % x
frame.applymap(format)
之所以叫applymap,是因为Series有一个应用于元素级函数的map方法:
frame[\'e\'].map(format)
虽然许多pandas函数(如reindex)都要求标签唯一,但这并不是强制的。
obj = Series(range(5), index=[\'a\', \'a\', \'b\', \'b\', \'c\'])
obj.index.is_unique   #False
索引的`is_unique属性可以告诉你它的值是否唯一。obj[\'a\']会返回两个值。
NA值会自动被排除。通过skipna选项可以禁用该功能。
意思是,df.mean(axis=1,skipna=False)会计算水平方向的均值,并且,有NA出现,均值也会是NA,而不是忽视它。
idxmin返回最小值的索引
idxman返回最大值的索引


有些汇总统计是通过参数对计算出来的。
看几个DataFrame,他们的数据来自Yahoo!Finance的股票价格和成交量。
import pandas.io.data as web
all_data = {}
for ticker in [\'AAPL\', \'IBM\', \'MSFT\', \'GOOG\']:
    all_data[ticker] = web.get_data_yahoo(ticker)
price = DataFrame({tic: data[\'Adj Close\']
                   for tic, data in all_data.iteritems()})
volume = DataFrame({tic: data[\'Volume\']
                    for tic, data in all_data.iteritems()})

计算价格的百分数变化:
returns = price.pct_change()
Series的corr方法计算两个Series中重叠的、非NA的、按索引对齐的值的相关系数。与此类似,cov用于计算协方差。
returns.MSFT.corr(returns.IBM)
returns.MSFT.cov(returns.IBM)
利用DataFrame的corrwith方法,可以计算其列或行跟另一个Series或者DataFrame之间的相关系数。
returns.corrwith(returns.IBM)
#等价于
returns.corr()[\'IBM\']
无论如何,在计算相关系数之前,所有的数据项都会按标签对齐。
unique函数可以得到Series中唯一值数组。
value_counts函数用于计算Series中各值出现的频率。
isin用于选取矢量化集合的成员资格。
这几个函数都是Series数据的方法!
result = data.apply(pd.value_counts).fillna(0)
利用上面这个方法,可以对df数据每列出现的数值频率进行统计,同时,对有的列中没有出现的数值的频率为NA的值设置为0
apply看来这个函数还是很有用啊,它是默认从列角度(axis=0)去应用里边的函数。而applymap是元素级应用函数。
之前看一篇文章,机器学习系列(3)_逻辑回归应用之Kaggle泰坦尼克之灾2,当中遇到缺失数据之后,运用机器学习的方法,结合其他变量拟合预测出值,然后作为缺失值的填充。
而本书立足于数据分析,从处理数据角度出发,因此,不会采用那么复杂的方法。这里,是要介绍一些操作数据的函数方法,这是基础,是之后处理数据的基本功!缺失数据也是重中之重!
pandas的设计目标之一就是让缺失数据的处理任务尽量轻松。例如,pandas对象上的描述统计都排除了缺失数据!
string_data = Series([\'aardvark\', \'artichoke\', np.nan, \'avocado\'])
string_data
0     aardvark
1    artichoke
2          NaN
3      avocado
dtype: object
Python内置的None值也会被当做NA处理。

dropna方法可能比较实用一点。
from numpy import nan as NA
data = Series([1, NA, 3.5, NA, 7])
data.dropna()
对于一个Series, dropna返回一个仅含非空数据和索引值的Series。
0    1.0
2    3.5
4    7.0
dtype: float64
而对于一个DataFrame对象,事情就有点复杂了。dropna默认丢弃任何含有缺失值的行。
data = DataFrame([[1., 6.5, 3.], [1., NA, NA],
                  [NA, NA, NA], [NA, 6.5, 3.]])
cleaned = data.dropna()
data

cleaned
    0    1    2
0    1.0    6.5    3.0
传入how=\'all\'将只丢弃全为NA的行。要用这种方式丢弃列,只需要传入参数axis=1。
data.dropna(how=\'all\')
0    1    2
0    1.0    6.5    3.0
1    1.0    NaN    NaN
3    NaN    6.5    3.0
另一个滤除DataFrame行的问题涉及时间序列。假设只想留下一部分观测数据,可以用tresh参数实现。
df = DataFrame(np.random.randn(7, 3))
df.ix[:4, 1] = NA; df.ix[:2, 2] = NA
df
       0        1             2
0    -0.577087    NaN            NaN
1    0.523772    NaN            NaN
2    -0.713544    NaN            NaN
3    -1.860761    NaN            0.560145
4    -1.265934    NaN            -1.063512
5    0.332883    -2.359419    -0.199543
6    -1.541996    -0.970736    -1.307030
df.dropna(thresh=3)
保留至少3个非空值的行。
        0        1            2
5    0.332883    -2.359419    -0.199543
6    -1.541996    -0.970736    -1.307030
对于大多数情况而言,fillna方法是最主要的函数。通过一个常数调用fillna就会将缺失值替换为那个常数。df.fillna(0)。
若是通过一个字典调用fillna,就可以实现对不同的列填充不同的值。
df.fillna({1:0.5,3:-1})
fillna默认会返回新对象,但也可以对现有对象进行就地修改:
df.fillna(0,inplace=True)
对reindex有效地那些插值方法,也可用以fillna。
df = DataFrame(np.random.randn(6, 3))
df.ix[2:, 1] = NA; df.ix[4:, 2] = NA
df
df.fillna(method=\'ffill\', limit=2)
# 有很多灵活的填充方式
data = Series([1., NA, 3.5, NA, 7])
data.fillna(data.mean())


层次化索引(hierarchical indexing)是pandas的一项重要功能,它使你能在一个轴上拥有多个(两个以上)索引级别。
抽象点说,它使你能以低纬度形式处理高纬度数据。
data = Series(np.random.randn(10),
              index=[[\'a\', \'a\', \'a\', \'b\', \'b\', \'b\', \'c\', \'c\', \'d\', \'d\'],
                     [1, 2, 3, 1, 2, 3, 1, 2, 2, 3]])
data
a  1   -0.204708
   2    0.478943
   3   -0.519439
b  1   -0.555730
   2    1.965781
   3    1.393406
c  1    0.092908
   2    0.281746
d  2    0.769023
   3    1.246435
dtype: float64
这段数据可以通过其unstack方法被重新安排到一个DataFrame中:
data.unstack()
    1            2            3
a    -0.204708    0.478943    -0.519439
b    -0.555730    1.965781    1.393406
c    0.092908    0.281746    NaN
d    NaN            0.769023    1.246435
unstack的逆方法是stack.
不要将索引名称(index.names)跟轴标签混为一谈!
有时,你需要重新调整某条轴上各级别的顺序,或根据指定级别上的值对数据进行排序。
swaplevel接受两个级别编号或名称,并返回一个互换了级别的新对象(但数据不会发生变化)
许多对DataFrame和Series的描述和汇总统计都有一个level选项,它用于指定在某条轴上求和的级别。
这其实是利用了pandas的groupby功能。
人们经常想要将DataFrame的一个或多个列当做行索引来用,或者可能希望将行索引变成DataFrame的列。
frame = DataFrame({\'a\': range(7), \'b\': range(7, 0, -1),
                   \'c\': [\'one\', \'one\', \'one\', \'two\', \'two\', \'two\', \'two\'],
                   \'d\': [0, 1, 2, 0, 1, 2, 3]})
frame

DataFrmae的set_index函数会将其一个或多个列转换为行索引,并创建一个新的DataFrame:
frame2 = frame.set_index([\'c\', \'d\'])

默认情况下,那系列会从DataFrame中移除,但也可以将其保留下来。
frame.set_index([\'c\', \'d\'], drop=False)

reset_index的功能跟set_index刚好相反,层次化索引的级别会被转移到列里边。
frame2.reset_index()
