Python 的 DataFrame 摘要

作者: , 共 5053 字 , 共阅读 0

Python 数据分析工具 pandas 中以 DataFrame 和 Series 作为主要的数据结构。

Series 是一个数据序列。DataFrame 是一张数据表(可以理解由多个 Series 构成,每个 Series 为一列)。DataFrame 和 Excel 和数据库的数据表类似(实际结构更复杂,因为支持多重索引),因此可以对其做类似 Excel 数据表的排序、筛选、聚合、透视表等操作,也可以做类似于数据库数据表的多表关联( join )等操作。

1、建立 DataFrame 对象

df = pd.DataFrame() #创建DataFrame对象 
df = pad.DataFrame([[1,2],[3,4]], columns=list('AB')) 

1.1、从文件读入

df = pandas.read_json('abc.json')

# 首先输入csv文本地址,然后分割符选择等等
df = pandas.read_csv('abc.csv', sep=';', nrows=2) 

1.2、导出数据

# 转为list of list,columns丢失
l = df.values.tolist() 

# 转为list of dict
d = df.to_dict("records")

1.3、保存到文件

# 要支持中文,python2必须指定encoding。python3已默认使用utf8
df.to_csv('abc.csv', encoding="utf8") 

#写入读取excel数据,pd.read_excel读取的数据是以DataFrame形式存储
df.to_excel('foo.xlsx',sheet_name='Sheet1');
pd.read_excel('foo.xlsx', 'Sheet1', index_col=None, na_values=['NA'])

#写入读取HDF5数据
df.to_hdf('foo.h5','df');pd.read_hdf('foo.h5','df')

2、查看 DataFrame 数据及属性

df.dtypes #查看各行的数据格式
df['col1'].astype(int)#转换某列的数据类型
df.head() #查看前几行的数据,默认前5行
df.tail() #查看后几行的数据,默认后5行
df.index #查看索引
df.columns #查看列名
df.values #查看数据值
df.describe() #描述性统计
df.T #转置

3、选择数据

df[1:-3] # 获取1到倒数第三行
df.ix[1:3] # 同上 
df.ix[1:3[1,3]]#获取1列3列的1~3行数据
df['c1'] # 选择列
df.c1 # 效果同上
df.columns[[0,1,3]] # zero indexed

# 选择其中指定的列
df = pd.DataFrame(df, columns=['a', 'b'])
df = df[['a', 'b']]
df = df.loc[:, ['a', 'b']]
df = df.iloc[:, 0:2]

需要注意 DataFrame 取下标和索引速度非常慢,不建议对其做 for 循环操作,若要做循环操作,建议两种替换方案,一种使用内建函数( apply、map、trasnform )等,另外一种将每列 Series 转为 list 之后处理( col_list = df.col.tolist())。

4、遍历数据

遍历每行:

# 下面每个 row 是一个 series
for index, row in df.iterrows():
    print(index, row['col1'], row['col2'])

# 下面每个 row 是一个命名的tuple,注意第一个元素为index,所以实际列从1开始索引。
for row in df.itertuples():
    print(row[1], getattr(row, "col2")

# 设置 index=False,去掉第一个元素的index
for row in df.itertuples(index=False):
    print(row[1], getattr(row, "col2")

遍历每列:

for name, column in df.items():
    print(name, column)

5、筛选数据(保留对应的行)

# 将要过滤的数据放入字典中,使用isin对数据进行筛选,返回行索引以及每行筛选的结果,若匹配则返回ture
alist = ['023-18996609823']
df['code'].isin(alist) 
# 获取匹配结果为ture的行
df[df['code'].isin(alist)] 

df[df.value>0]

# 使用正则表达式进行模糊匹配,*匹配0或无限次,?匹配0或1次
df[df['plan'].str.contains(r'.*?语音CDMA.*')]

6、删除数据

df[columns].drop_duplicates() #剔除重复行数据
df[df.isnull()]
df[df.notnull()]
df.dropna()#将所有含有nan项的row删除
df.dropna(axis=1,thresh=3) #将在列的方向上三个为NaN的项删除
df.dropna(how='ALL')#将全部项都是nan的row删除填充值

6.1、删除特定列

del df.col1  # 删除列 inplace
df = df.drop('column_name', 1) # 返回删除后的新的DataFrame
df.drop('column_name', axis=1, inplace=True)
df.drop([df.columns[[0, 1, 3]]], axis=1, inplace=True)   # Note: zero indexed

7、修改数据

df.fillna(0)
df.fillna({1:0,2:0.5}) #对第一列nan值赋0,第二列赋值0.5
df.fillna(method='ffill') #df
df.ix[1:3[1,3]]=1#所选位置数据替换为1   
df['支局_维护线'] = df['支局_维护线'].str.replace('巫溪分公司(.{2,})支局','\1')#可以使用正则表达式

# 指定或修改列
df.columns = list("ABCD")

8、apply & transform

df.apply(lambda col: sum(col), axes=0) # 对每列求和
df.apply(lambda row: sum(row), axes=0) # 对每行求和
df.col2 = df.col1.apply(lambda col: sum(col))    # 对col1列求和
df.col3 = df.col3.apply(lambda x: x+1) # col3列都加1
df = df.applymap(lambda x:x+1) # 每个元素都加1
df.transform(lambda x:x+1)     # 效果同上,相当于inplace的applymap

8.1、修改列名

df.rename(columns={'A':'a', 'C':'c'}, inplace=True)
df.columns = ['A', 'B', 'C']

8.2、新增列

# 新增了一列 
df['new_column'] = df['old_column']   

# 这样不会新增列,只会跟原列起了个别名引用
df.new_column = df['old_column']  

9、聚合数据(类似 SQL 中的 GROUP BY 或 HAVING):

df.groupby(['col1', 'col2'])
#上面的简单写法
data_obj.groupby('支局_维护线')['用户标识'] 
#按支局进行汇总对用户标识进行计数,并将计数列的列名命名为ADSL
adsl_obj.groupby('支局_维护线')['用户标识'].agg([('ADSL','count')])

df = df.groupby(['col1', col2']).sum()
df = df.reset_index()

10、透视表

# 先聚合再透视。
df = df.pivot(index='A', columes='B', values='C') 

# 复杂一点的,支持同时聚合
table = pivot_table(df, values='D', index=['A', 'B'], columns=['C'], aggfunc=np.sum) 

11、合并数据集(类似于数据库的 union/union all )

行数增加。

# df2放在df1后面,注意append会返回一个新的对象,不是在原对象上修改。
df1 = df1.append(df2) 

df = pandas.concat([df1, df2], ignore_index=True) # 等价于append

列数增加。

12、Join 数据集(类似于数据库的 left/right/inner/outer join )

# 和sql的join类似,on index_key
df = pandas.concat([df1, df2], axis=1) 

# df1和df2将用户标识当成重叠列的键合并两个数据集,inner表示取两个数据集的交集.
merge(df1, df2, on='abc',how='inner')

pd.merge(left, right, how='inner', on=None, left_on=None, right_on=None,
         left_index=False, right_index=False, sort=True,
         suffixes=('_x', '_y'), copy=True, indicator=False)

13、排序

df.sort_values(by, axis=0, ascending=True, inplace=False, kind='quicksort', na_position='last')

14、画图

Q. E. D.

类似文章:
编程 » pandas, python
一个最直接的方法如下,最后得到的s2就是一个普通的pandas.DataFrame,可以继续处理:
编程 » pandas, numpy, Python, C++
首先任意定义一个结构,注意不要用 std::string 非平凡布局的变量,用 char[] 代替:
Excel 多表合并和查询是一个应用很广泛的问题。下面是一个简单的例子,我们需要从两张数据表里,得出每个行业的股票波动率平均值。第一个数据表保存了股票和行业的对应关系,有两列,第一列为股票名,第二列为每只股票对应的行业。第二张表保存了各个股票在各个交易日的收盘价和前收盘价,有四列,第一列是股票名,第二列为交易日,第三列和第四列分别为股票在这个交易日的前收盘价和收盘价。
编程 » Excel, 数据库
在前面的文章里,我已经提到Excel 数据本身可以当做一张 SQL 查询的数据表,并在 Excel 内进行数据库运算操作。数据库查询函数可以用我之前写的Excel 数据库操作函数类。我们可以用以下方式
编程 » C++, 数据容器, folly
folly::dynamic提供类似于C++的动态类型。和std::any可以容纳任意类型不一样,folly::dynamic只支持保存以下几种类型:
编程 » Python
在 Python3 以上,通常说的字符串是指unicode字符串,以下将不再重复强调。
编程 » NaN, Python, Javascript, JSON
一般而言,在 Python 里:
IT »
最近试用了一些 markdown 编辑器,之前最有名的是 simplemde, 2017 年之后未更新,有人在此基础上做了个 easymde,现在还有一些更新。
2014-03-25 更新:我已经将该类修改成函数形式,并增加新功能,参见更新 Excel 的数据库查询函数库
在 Python 中操作文件或字符串时,有时候会碰到 UnicodeDecodeError 异常:
最近分级 A 的价格不断被打压,再加上股市处于下降通道,看跌期权价值不断提升,导致分级 A 出现一个历史上绝无仅有的买入机会。
假设我手里有一些股票,成分和指数差不多,想用股指期货去对冲,应该卖空多少数量的股指期货?