python数据分析—基本数据结构
一、简介:
pandas是python的一个开源工具包,为Python提供了高性能,简单易用的的数据结构和数据分析工具。 pandas提供了类表格的统计操作和类SQL操作,方便数据的预处理工作,提供强大的缺失值处理功能。
pandas的特色功能:
- 索引对象:包括简单的索引和多次层索引。
- 引擎集成组合:用于汇总和转换数据集合。
- 日期范围生成器以及自定义日期偏移(实现自定义频率)。
- 输入工具和输出工具:从各种格式的文件中(csv、delimited、excel2003)加载表格数据,以及快速收高效的从PyTables/HDFS5格式中保存和加载Pandas对象。
- 标准数据结构的稀疏形式:可以用于存储大量缺失或者大量一致的数据。
- 移动窗口统计(滚动平均值、滚动标准偏差等)
二、数据结构:
2.1 .Series:
是pandas的重要数据结构,类似于一维数组与字典的集合,是一个有标签的一维数组,同时标签在Pandas中有对应的数据类型‘index’.
2.1.1 Series的创建:
Series在创建时可以接受很多种输入,比如:list、numpy的ndarray、dict甚至标量。Index可以有选择的传入。
- 传入list
import pandas as pd
list=[1,2,3,4,5,6]
obj=pd.Series(list)
print(obj)
0 1
1 2
2 3
3 4
4 5
5 6
dtype: int64
在定义Series时没有指定索引,因此pandas将自动创建0~n-1的序列作为索引。Series对象在输出时,每一行为Series的一个元素,左侧为索引,右侧为值。
- 传入字典
import pandas as pd
dict={'a':1,'b':2,'c':3}
obj=pd.Series(dict)
print(obj)
a 1
b 2
c 3
dtype: int64
通过字典创建Series对象时,索引默认为字典的键值,也可以通过index参数指定。
import pandas as pd
dict={'a':1,'b':2,'c':3}
obj=pd.Series(dict,index=['a','b','y'])
print(obj)
a 1.0
b 2.0
y NaN
dtype: float64
从上面可以看出,字典中与指定索引相匹配的值诶放到了正确的位置,而不能匹配的索引对应的值为标记为NAN,这个过程叫做数据对齐。NaN(not a number),在Python中表示缺失值。
- 传入ndarray
import pandas as pd
import numpy as np
list=['a','b','c','d','e','f']
obj=pd.Series(np.array(list))
print(obj)
0 a
1 b
2 c
3 d
4 e
5 f
dtype: object
2.1.2 Series访问
- Series像一个ndarray,可以使用类似于访问ndarray的方式对其进行访问。
import pandas as pd
import numpy as np
list=['a','b','c','d','e','f']
obj=pd.Series(np.array(list))
print(obj)
'c'
- Series像一个ndarray,可以用类似访问ndarray的方式进行访问。
- Series又像一个固定大小的dict,所以可以用iloc()函数和loc()函数对Series进行访问。Series可以理解为一个定长、有序的 ‘字典’ 结果。
loc()函数:loc()通过行标签索引行数据;结果是左闭右闭
import numpy as np
import pandas as pd
list = [[1, 2, 3, 4, 5], [6, 7, 8, 9, 10]]
obj = pd.Series(list, index=['a', 'b']) #设置行标签为['a','b']
#print(obj)
print(obj.loc['a':'b']) # 按照行索引索引数据
a [1, 2, 3, 4, 5]
b [6, 7, 8, 9, 10]
dtype: object
iloc()函数:iloc()函数通过行号进行索引数据;结果是左闭右开。iloc也可以取指定行列,只不过得按切片形式索引,不能直接拿标签索引来做。
import numpy as np
import pandas as pd
list = [[1, 2, 3, 4, 5], [6, 7, 8, 9, 10]]
obj = pd.Series(list, index=['a', 'b'])
#print(obj)
print(obj.iloc[0:1]) #iloc()按照行号进行
a [1, 2, 3, 4, 5] #结果只有'a',可以看出iloc()结果是左闭右开
dtype: object
- 可以直接通过类似数组和类似属性的方式对其进行访问。
import numpy as np
import pandas as pd
list = [[1, 2, 3, 4, 5], [6, 7, 8, 9, 10]]
obj = pd.Series(list, index=['a', 'b']) # 设置行标签为['a','b']
# print(obj)
#print(obj.loc['a':'b']) # 按照行索引索引数据
obj['c'] = [1, 2, 3, 4, 5]
print(obj)
print(obj.b)
a [1, 2, 3, 4, 5]
b [6, 7, 8, 9, 10]
c [1, 2, 3, 4, 5]
dtype: object
[6, 7, 8, 9, 10]
2.1.3 Series的操作
- 像数组一样对Series进行遍历的操作是没有必要的。
- Numpy对ndarray的操作对Series同样也可以,但由于索引的原因,操作时要注意数组对齐的问题。
2.1.4 Series的name属性
Series对像的索引与值可以通过属性index和values属性获取。
import numpy as np
import pandas as pd
list = [[1, 2, 3, 4, 5], [6, 7, 8, 9, 10]]
obj = pd.Series(list, index=['a', 'b']) # 设置行标签为['a','b']
#print(obj.index)
a=obj.values
print(a)
for i in a:
print(i)
print(type(i))
[list([1, 2, 3, 4, 5]) list([6, 7, 8, 9, 10])]
[1, 2, 3, 4, 5]
<class 'list'>
[6, 7, 8, 9, 10]
<class 'list'>
2.1.5 Series与ndarray
import numpy as np
import pandas as pd
list = [[1, 2, 3, 4, 5], [6, 7, 8, 9, 10]]
obj = pd.Series(list, index=['a', 'b']) # 设置行标签为['a','b']
#print(obj.index)
a=obj.index
b=obj.values
print(a)
print(type(a))
print(b)
print(type(b))
Index(['a', 'b'], dtype='object')
<class 'pandas.core.indexes.base.Index'> #index
[list([1, 2, 3, 4, 5]) list([6, 7, 8, 9, 10])]
<class 'numpy.ndarray'> #values
Series是一种类似于一维数组的对象,它由一组数据(各种NumPy数据类型)以及一组与之相关的数据标签(即索引)组成。
2.2 DataFrame
DataFrame是有标签的二维数组,类似于表格、SQL中的table,或者Series对象的dict。DataFrame分行索引(index)和列索引(columns)。
2.2.1 DataFrame的创建
DataFrame可以接收很多种输入,包括一维的ndarray,list,dict 或者Series的dict ;二维的ndarray,一个Series,以及其他的DataFrame等。在创建DataFrame时行索引和列索引可以通过index和columns来指定,没有给出,则默认从0开始。
- 值为list的dict创建DataFrame
默认使用字典中的键作为列索引。
import numpy as np
import pandas as pd
dict = {'a': [1, 2, 3], 'b': [4, 5, 6], 'c': [7, 8, 9]}
obj=pd.DataFrame(dict)
print(obj)
a b c
0 1 4 7
1 2 5 8
2 3 6 9
用户可以使用columns参数指定列索引,字典中的数据会按照指定顺序排列,未定义的数据会标记为NaN。
import numpy as np
import pandas as pd
dict = {'a': [1, 2, 3], 'b': [4, 5, 6], 'c': [7, 8, 9]}
obj = pd.DataFrame(dict, columns=['b', 'c', 'd'])
print(obj)
b c d
0 4 7 NaN
1 5 8 NaN
2 6 9 NaN
- 值为Series对象的dict创建DataFrame对象,DataFrame中的每一列都可以看作是一个Series,有索引
import numpy as np
import pandas as pd
dict = {'one': pd.Series([1, 2, 3], index=['a', 'b', 'c']), 'two': pd.Series([4, 5, 6], index=['c', 'd', 'e'])}
obj=pd.DataFrame(dict)
print(obj)
print(obj.index) # 获取行索引index
print(obj.columns) # 获取列索引columns
print(obj.values) # 获取值
one two
a 1.0 NaN
b 2.0 NaN
c 3.0 4.0
d NaN 5.0
e NaN 6.0
Index(['a', 'b', 'c', 'd', 'e'], dtype='object')
Index(['one', 'two'], dtype='object')
[[ 1. nan]
[ 2. nan]
[ 3. 4.]
[nan 5.]
[nan 6.]]
- 通过一个元素为dict的list创建DataFrame对象
import numpy as np
import pandas as pd
list = [{'a': 1, 'b': 2}, {'c': 3, 'd': 4}]
obj = pd.DataFrame(list)
print(obj)
print(obj.index) # 获取行索引index
print(obj.columns) # 获取列索引columns
print(obj.values) # 获取值
a b c d
0 1.0 2.0 NaN NaN
1 NaN NaN 3.0 4.0
RangeIndex(start=0, stop=2, step=1)
Index(['a', 'b', 'c', 'd'], dtype='object')
[[ 1. 2. nan nan]
[nan nan 3. 4.]]
- 通过Series对象创建DataFrame对象
一个Series就是一列
import numpy as np
import pandas as pd
ser = pd.Series([1, 2, 3], index=['a', 'b', 'c'])
obj = pd.DataFrame(ser, columns=['d'])
print(obj)
print(obj.index) # 获取行索引index
print(obj.columns) # 获取列索引columns
print(obj.values) # 获取值
d
a 1
b 2
c 3
Index(['a', 'b', 'c'], dtype='object')
Index(['d'], dtype='object')
[[1]
[2]
[3]]
注意:
- DataFrame的行索引、列索引与数据可以通过index、columns、values获取。
import numpy as np
import pandas as pd
dict = {'a': [1, 2, 3], 'b': [4, 5, 6], 'c': [7, 8, 9]}
obj = pd.DataFrame(dict, columns=['b', 'c', 'd'])
print(obj.index) #获取行索引index
print(obj.columns) #获取列索引columns
print(obj.values) #获取值
RangeIndex(start=0, stop=3, step=1)
Index(['b', 'c', 'd'], dtype='object')
[[4 7 nan]
[5 8 nan]
[6 9 nan]]
2.2.2 DataFrame的访问
- 行索引 df.loc(m,n)行索引,左右都闭 或者df.ioc(m,n)左闭右开,访问某一行
import pandas as pd
import numpy as np
#randn(m,n)从标准正太分布中返回4行5列个值
df = pd.DataFrame(np.random.randn(4, 5), columns=list('ABCDE'), index=range(1, 5))
print(df)
A B C D E
1 -1.201955 0.190376 0.562827 -0.404948 1.487477
2 -0.605632 0.154709 0.227973 0.281183 -0.374427
3 -0.402541 0.462260 0.151157 -0.475742 -0.737443
4 -0.162970 -0.452726 -0.870124 0.189586 -0.278887
import pandas as pd
import numpy as np
df = pd.DataFrame(np.random.randn(4, 5), columns=list('ABCDE'), index=range(1, 5))
print(df)
#打印一行数据
print(df.loc[1]) #行索引为1的
print(df.iloc[1]) #行号为1的
A B C D E
1 1.827533 -0.977781 -0.151347 0.394917 -0.045045
2 1.028146 1.098714 0.592538 -0.674038 1.535927
3 -1.174053 -0.186535 0.718851 -2.732119 0.336701
4 0.605772 0.561915 -0.459173 -1.444412 -0.970409
#行索引为1的是第一行的数据
A 1.827533
B -0.977781
C -0.151347
D 0.394917
E -0.045045
Name: 1, dtype: float64
#行号为1的是第2行的数据
A 1.028146
B 1.098714
C 0.592538
D -0.674038
E 1.535927
Name: 2, dtype: float64
- 列索引 df[‘column’] 访问某一列
import pandas as pd
import numpy as np
df = pd.DataFrame(np.random.randn(4, 5), columns=list('ABCDE'), index=range(1, 5))
print(df)
print(df['A'])
A B C D E
1 -2.252381 -2.114396 -0.862908 0.597926 0.321168
2 -0.302558 -1.231085 -0.475849 0.302359 0.159897
3 -0.188017 0.236983 2.137463 1.516719 1.289887
4 0.590265 0.411547 -0.083675 0.585107 -0.740355
#列索引为'A'的值
1 -2.252381
2 -0.302558
3 -0.188017
4 0.590265
Name: A, dtype: float64
- df[‘column’][n]访问某一个元素的值
df = pd.DataFrame(np.random.randn(4, 5), columns=list('ABCDE'), index=range(1, 5))
print(df)
print(df['A'])
print(type(df['A'])) #查看df['A']的类型
print(df['A'][1])
A B C D E
1 0.488215 1.345990 0.474998 0.117813 0.390442
2 -1.007240 0.264216 0.934925 0.423139 0.592207
3 -1.386739 -0.330978 -0.562848 0.634387 -0.664225
4 -1.112840 0.081102 -0.132899 -0.076448 0.618742
#df['A']的值
1 0.488215
2 -1.007240
3 -1.386739
4 -1.112840
Name: A, dtype: float64
#df['A']的数据类型为Series,可以按照访问Series中元素的方法访问我们要的数据
<class 'pandas.core.series.Series'>
0.48821487181210205
- df.loc[m,n]访问行索引为m,列索引为n的值
import pandas as pd
import numpy as np
df = pd.DataFrame(np.random.randn(4, 5), columns=list('ABCDE'), index=range(1, 5))
print(df.loc[1]) #查看行索引以为1的结果的返回值类型
print(type(df.loc[1])) #查看行索引为1,列索引为'A'的结果的返回值类型
print(df.loc[1,'A']) #查看行索引为1,列索引为'B'的结果的返回值类型
print(df.loc[1]['B'])
A -0.335017
B 1.253011
C 0.717683
D -1.513980
E 0.357113
Name: 1, dtype: float64
#行索引为1的返回值数据类型为Series
<class 'pandas.core.series.Series'>
#行索引为1,列索引为'A'的结果
-0.33501653050785835
#行索引为1,列索引为'B'的结果
1.2530110119892786
2.2.3 DataFrame的操作
DataFrame本身可以进行很多算数操作,包括加、减、乘、除以及转置,numpy对矩阵的一系列从操作都可以用于DataFrame,但要注意数据对齐。
- DataFrame对象的drop操作
用法:DataFrame.drop(labels=None,axis=0, index=None, columns=None, inplace=False)
参数说明: labels 就是要删除的行列的名字,用列表给定 axis 默认为0,指删除行,因此删除columns时要指定axis=1;
index 直接指定要删除的行 columns 直接指定要删除的列
inplace=False,默认该删除操作不改变原数据,而是返回一个执行删除操作后的新dataframe;
inplace=True,则会直接在原数据上进行删除操作,删除后无法返回。
删除行
import pandas as pd
import numpy as np
df = pd.DataFrame(np.random.randn(4, 5), columns=list('ABCDE'), index=range(1, 5))
print(df)
print(df.drop(1, axis=0,inplace=True)) #删除行索引为1的行,inplace=True表示在原来的基础上修改
print(df) # inplace=False返回一个新的对象
A B C D E
1 1.447141 -1.774092 -0.340348 -0.390352 -0.097137
2 0.771139 -0.126875 0.271016 1.341702 -1.714202
3 -0.923490 -0.031695 -0.124082 0.585022 -0.336363
4 -0.791192 -0.740612 -0.166458 -0.416313 1.214897
None
A B C D E
2 0.771139 -0.126875 0.271016 1.341702 -1.714202
3 -0.923490 -0.031695 -0.124082 0.585022 -0.336363
4 -0.791192 -0.740612 -0.166458 -0.416313 1.214897
删除列
import pandas as pd
import numpy as np
df = pd.DataFrame(np.random.randn(4, 5), columns=list('ABCDE'), index=range(1, 5))
print(df)
print(df.drop(['A','D'], axis=1,inplace=True)) #删除列索引为'A'、'B'的列
print(df)
A B C D E
1 -0.839346 1.523433 -1.723144 -0.910068 0.291090
2 -0.953989 2.410516 -0.888368 -1.032089 -0.769081
3 0.251137 -0.817246 0.451083 -0.822721 -1.419926
4 0.149927 0.595186 -0.388625 0.312590 0.111805
None
B C E
1 1.523433 -1.723144 0.291090
2 2.410516 -0.888368 -0.769081
3 -0.817246 0.451083 -1.419926
4 0.595186 -0.388625 0.111805
- DataFrame对象的del操作
del删除列,一次只能删除1列,直接在原对象上删除
import pandas as pd
import numpy as np
df = pd.DataFrame(np.random.randn(4, 5), columns=list('ABCDE'), index=range(1, 5))
print(df)
del df['A'] #删除列索引为'A'的列
print(df)
A B C D E
1 1.364634 -1.916636 -2.964419 1.157866 -0.353416
2 0.546747 -1.817599 -0.053800 -1.823036 -0.682654
3 0.295813 1.635711 -0.407629 1.929494 -1.530364
4 0.827149 0.416462 0.006249 0.200002 1.514046
B C D E
1 -1.916636 -2.964419 1.157866 -0.353416
2 -1.817599 -0.053800 -1.823036 -0.682654
3 1.635711 -0.407629 1.929494 -1.530364
4 0.416462 0.006249 0.200002 1.514046
- DataFrme对象的pop操作
直接在原对象上操作,删除一列,删除的列以Series对象返回
import pandas as pd
import numpy as np
df = pd.DataFrame(np.random.randn(4, 5), columns=list('ABCDE'), index=range(1, 5))
print(df)
df1=df.pop('E')
print(df)
A B C D E
1 2.082457 0.112071 -0.693167 0.146432 1.055799
2 0.618954 0.580420 -1.617344 1.764902 -1.208115
3 -0.123226 -3.696503 0.985780 1.266152 0.582168
4 -0.252736 0.721523 -0.687895 0.968123 1.401678
A B C D
1 2.082457 0.112071 -0.693167 0.146432
2 0.618954 0.580420 -1.617344 1.764902
3 -0.123226 -3.696503 0.985780 1.266152
4 -0.252736 0.721523 -0.687895 0.968123
- DataFrame对象增加列
直接给1列统一赋值为一样的值
import pandas as pd
import numpy as np
df = pd.DataFrame(np.random.randn(4, 5), columns=list('ABCDE'), index=range(1, 5))
print(df)
df['F']= 'm'
print(df)
A B C D E
1 -1.691858 -1.119025 -0.465698 -1.550146 0.274825
2 2.015004 -0.113981 1.080160 1.759140 -0.346518
3 -0.480312 -0.564740 0.100712 1.163879 -0.367650
4 0.516469 0.313909 -1.009504 -0.894583 -0.093504
A B C D E F
1 -1.691858 -1.119025 -0.465698 -1.550146 0.274825 m
2 2.015004 -0.113981 1.080160 1.759140 -0.346518 m
3 -0.480312 -0.564740 0.100712 1.163879 -0.367650 m
4 0.516469 0.313909 -1.009504 -0.894583 -0.093504 m
将其他列的值赋值给新列
df['F']= df['A'][:2]
print(df)
A B C D E
1 0.045964 0.027353 -1.519373 -1.480259 0.814998
2 -0.407421 -0.326698 -1.809421 0.329080 -1.750063
3 1.218356 1.828928 -1.166399 0.500363 0.630503
4 -0.084323 0.730724 -0.408536 0.375793 1.093167
A B C D E F
1 0.045964 0.027353 -1.519373 -1.480259 0.814998 0.045964
2 -0.407421 -0.326698 -1.809421 0.329080 -1.750063 -0.407421
3 1.218356 1.828928 -1.166399 0.500363 0.630503 NaN
4 -0.084323 0.730724 -0.408536 0.375793 1.093167 NaN
- 插入一列数据
import pandas as pd
import numpy as np
df = pd.DataFrame(np.random.randn(4, 5), columns=list('ABCDE'), index=range(1, 5))
print(df)
df.insert(0,'NEM',df['E']) #在第一列插入
print(df)
``
```python
A B C D E
1 -1.897143 0.404064 0.799515 0.067895 -0.048928
2 -0.210705 -0.248640 -0.321914 -1.434771 -1.732463
3 -0.604696 1.072780 1.043894 0.235450 1.157942
4 -0.294714 0.834883 -0.104012 -0.231545 -2.328798
NEM A B C D E
1 -0.048928 -1.897143 0.404064 0.799515 0.067895 -0.048928
2 -1.732463 -0.210705 -0.248640 -0.321914 -1.434771 -1.732463
3 1.157942 -0.604696 1.072780 1.043894 0.235450 1.157942
4 -2.328798 -0.294714 0.834883 -0.104012 -0.231545 -2.328798