0%

Python-Pandas数据结构操作

平时用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