平时用Python处理数据的时候,代码最开始都会无脑import numpy和pandas包,之前简单的整理了Numpy的用法,这次是pandas包的DataFrame(比较常见)的操作 > Pandas 是一个 Python包,提供快速、灵活和富有表现力的数据结构,旨在使“关系”或“标记”数据的使用既简单又直观。它的目标是成为用Python进行实际的、真实的数据分析的基础高级模块。此外,它还有更宏远的目标,即成为超过任何语言的最强大,最灵活的开源数据分析/操作工具。。。。
Pandas数据类型简单的分有Series和DataFrame两类,我粗略的理解相当于R语言的向量和数据框
Series可以接受字典dict、ndarry以及标量值等数据来源,比如:
从字典作为输入:
pd.Series({'b': 1, 'a': 0, 'c': 2})
从ndarry(Numpy的)作为输入,index
方法可返回series的索引,不指定index索引的话,默认是0开始编号;PS. pandas支持非唯一索引值。。。
s = pd.Series(np.random.randn(5), index=['a', 'b', 'c', 'd', 'e'])
s.index #索引
s.dtype #数据类型
从标量作为输入:
pd.Series(5., index=['a', 'b', 'c', 'd', 'e'])
之前说Series类似于R语言的向量,也是因为两者操作上也比较相似,比如切片等操作:
s = pd.Series(np.random.randn(5), index=['a', 'b', 'c', 'd', 'e'])
s[0]
s[:3]
s[s > s.median()]
s[[4, 3, 1]]
除了切片还返回值,还可以通过索引标签来返回值、赋值以及判断索引是否存在,比如:
s['a']
s['e'] = 12.
'e' in s
如果使用了不存在的索引,pandas则会报错(而R则是返回NA),但可以用get
方法来避免报错
s.get('f') == None
>>True
还可以对Series进行numpy函数操作,以及向量化操作(pandas会根据索引自动对齐进行运算,无法对齐的标签则返回NaN)
np.exp(s)
s + s
s[1:] + s[:-1]
DataFrame跟Series差不多,也支持多个数据结构的来源,如:
- 1D ndarray,list,dicts或Series的Dict
- two-dimensional ndarray
- ndarray
- Series
- DataFrame
比如一些常见的用法:
df = pd.DataFrame({'foo1': np.random.randn(5),
'foo2': np.random.randn(5)})
df.columns
或者来自于ndarray,其中len(df.index)
可查看行数,list(df.columns.values)
则可查看列名
data = np.array([[1, 2],
[3, 4]])
df = pd.DataFrame(data = data,
index = ["Row1","Row2"],
columns = ["Col1","Col2"])
print(df)
print(df.shape)
print(len(df.index))
print(list(df.columns.values))
还有比如创建空DataFrame
pd.DataFrame(np.nan, index=[0,1,2,3], columns=["A","B"])
个人感觉DataFrame一般都是从文件中直接读取用得比较多pd.read_csv
等等。。但还是有几个比较有用的函数,如:
DataFrame.from_dict
函数,其中加不加index有略微区别(前者A/B是column,后者加了orient
参数的话,A/B则变成了index,此时需要再设定column)
df = pd.DataFrame.from_dict(dict([('A', [1, 2, 3]), ('B', [4, 5, 6])]))
df = pd.DataFrame.from_dict(dict([('A', [1, 2, 3]), ('B', [4, 5, 6])]),
orient='index', columns=['one', 'two', 'three'])
DataFrame.from_records
函数则是用于ndarray类型的数据:
data = np.array([(1, 2., 'Hello'), (2, 3., 'World')])
pd.DataFrame.from_records(data, index = ("a","b"))
对DataFrame类型数据操作,相比较R语言来说,也非常类似,但也有点不同;比如在R中是以[,]
来获取数据框的值,而在Pandas中则不同,比较常用的切片行/列操作如下:
df = pd.DataFrame(np.array([[1,2,3], [4,5,6], [7,8,9]]), columns = ["A","B","C"])
# 切片行
df[:1]
# 指定列
df["A"]
还可以通过loc[]
和iloc[]
来获取指定数值,如下:
# 1行1列的值
df.iloc[0][0] # 等价于 df.iloc[0,0]
df.loc[0]['A'] # 等价于 df.loc[:,'A']
# 切片行/列
df.iloc[0] # 等价于 df.iloc[0][:] 或者 df.loc[0]
df.loc[:,"A"] # 等价于 df.loc[:]["A"]
也可用于赋值创建新列/行
df.loc[3] = [10,11,12] # 添加行
df["D"] = df.index # 添加列
df.loc[:, "D"] = df.index # 同上
也可以通过类似于R语言的方式,通过at[]
或者iat[]
方法,如下:
df.at[0,'A']
df.iat[0,0]
DataFrame可以通过set_index
方法,可以设置单索引和复合索引(类似于交叉表的形式。。。个人觉得),而reset_index
则是逆操作
df.set_index('C')
能新建行/列,当然也能删除行/列,用drop
方法,其中axis=1
对应列,为axis=0
对应行,inplace
为True则直接改变df
原数据,如下:
df.drop("D", axis=1, inplace=True)
df.drop(df.columns[3], axis=1) # 同上
df.drop(3, axis=0, inplace = True)
df.drop(df.index[3], axis=0) # 同上
删除列还可以用简单的del
方法
del df['A']
使用drop_duplicates
方法可以查看指定列是否有重复并指定保留其中某一个
df.drop_duplicates(["A"], keep='last')
对行名和列名重命名也是一个比较常见的需求,可使用rename
方法
df.rename(index = {0:1, 1:2, 2:3})
df.rename(columns = {"A":"col1", "B":"col2", "C":"col3", "D":"col4"}, inplace = True)
判断缺失值,可用isnull
方法
df.isnull()
去除缺失值,可用dropna
方法
df.dropna()
df.dropna(axis=1, thresh=2)
有删缺失值,则肯定是补缺的方法,可用fillna
方法
df.fillna(value=100)
df.fillna(value={"A":100}) # 指定列中的缺失值
替换DataFrame中的数值也有专门的方法replace
,可以用df.replace(to_replace, value)
形式,也可以用字典形式除了常规替换,还可以用regex
参数来做正则匹配
df.replace([1,2,3,4], [11,12,13,14])
df.replace({1:2, 2:3})
df.replace('[A-Z]', 0, regex = True)
此外,类似R语言的rblind
或者cblind
,Pandas也有类似的方法join
来合并DataFrame
对于R语言的apply
家族函数,Pandas也有apply
方法:
df["A"].apply(doubler) # 对列
df.loc[0].apply(doubler) # 也可以对行
还要一些比较复杂的操作,如:
pivot()
stack()
,unstack()
melt()
如果想历遍DataFrame,可以用iterrows
方法
for index, row in df.iterrows() :
print(row["A"], row["B"])
参考资料:
https://www.pypandas.cn/docs/getting_started/dsintro.html#dsintro
https://www.datacamp.com/community/tutorials/pandas-tutorial-dataframe-python