生成对象和获取对象的基本信息
pandas中DataFrame生成对象。
对于属性和索引直接为空的对象,直接传入矩阵即可。
对于要指定索引和属性的数据,需要传入对应参数:
df = pd.DataFrame(data,index=indexs,columns=list("ABCD"))
当简单做测试的时候,可以用字典进行生成对象:
data = {'a':[1,2,3], 'b':[2,3,4], 'c':[3,4,5]}
df = pd.DataFrame(data)
'''
a b c
0 1 2 3
1 2 3 4
2 3 4 5
'''
补:此时是生成索引是自增的,当前的键值对是从列的角度;如果要指定索引的话,还是得在列的角度,那么对应的值(键值对)的列表(list)/中的元素/就要变成字典(dict)了。
df = pd.DataFrame({'a':{'A':1, 'B':2}, 'b':{'A':3, 'B':4}, 'c':{'A':5, 'B':6}})
'''
a b c
A 1 3 5
B 2 4 6
'''
如上,当值为list
时,生成DataFrame,当值为基本数据的时候,生成Series;键在DataFrame时为列属性,在Series时为索引。
如果要增加一列的话,将'1'
改为''
即可。
df['d'] = '1'
'''
a b c d
0 1 2 3 1
1 2 3 4 1
2 3 4 5 1
'''
此时加入的数据都是独立的,即改变某行不会影响其他行。
df.loc[0, 'd'] = '*'
df.loc[0, 'e'] = '*'
'''
a b c d e
0 1 2 3 * *
1 2 3 4 1 1
2 3 4 5 1 1
'''
要想获取其中的数据,就用values
属性,其返回值是
,如果不熟悉需要用tolist()
方法转为list
。
df_nd = df.values
'''
[[1 2 3 '*' '*']
[2 3 4 '1' 1]
[3 4 5 '1' 1]]
'''
df_ls = df_nd.tolist()
'''
[[1, 2, 3, '*', '*'], [2, 3, 4, '1', 1], [3, 4, 5, '1', 1]]
'''
既然说到了values
属性,自然而然要延伸出1.获取属性,2.获取索引 3.查看每一列的类型。在此我简单列出来函数及展示:
print(df.index)
'''
RangeIndex(start=0, stop=3, step=1)
'''
print(df.columns)
'''
Index(['a', 'b', 'c', 'd', 'e'], dtype='object')
'''
print(df.dtypes)
'''
a int64
b int64
c int64
d object
e object
dtype: object
'''
注意我没有特别指定索引,所以相当于一个自增主键;d
列为str
, e
列因为在int
中加入了str
,所以都是object
类。诚然,正常业务中,一个属性应该是一种类型的,所以用这个方法还是很有帮助的。
修改对象
对于各种数据,常常涉及到:原来的索引是默认自增序列,现在想让某个属性作为索引(此时有两种,一是直接改原来的属性;二是将索引改名。差别在于新的索引是否有属性名);
增
增加属性直接给新属性赋空,上面有提到;
增加索引相当于直接增加一行数据。
增加一列值:
df['f'] = [2,2,3]
'''
a b c d e f
A 1 2 3 * * 2
B 2 3 4 1 1 2
C 3 4 5 1 1 3
'''
只要保证新加入这一列的行数与现有行数相同即可。
增加一行:
只需要再写一个DataFrame格式的数据,然后.append()
上去即可,注意,ignore_index = True
参数表示清除目前的索引,改为自增的,默认为False;还有新的DF数据必须指定index
,而且index
必须是集合格式。
new_df = pd.DataFrame({'a':4, 'b':5, 'c':6, 'd':7, 'e':8, 'f':9}, index = ["D"])
df = df.append(new_df, ignore_index = False)
'''
a b c d e f
A 1 2 3 * * 2
B 2 3 4 1 1 2
C 3 4 5 1 1 3
D 4 5 6 7 8 9
'''
删
目前我的水平并不需要关心删除,只要能跑通即可。
查
查数据主要有两个方向,按行,按列。
按行主要是.loc[]
和 .iloc[]
。前者主要是在有索引的时候用索引名进行定位;后者则是基于位置的。
以loc
为例(我常用):
df.loc[index_name, col_name]
可以看出,在二维数据中,行和列都指定了,就会确定出唯一的数据;当只指定行或列,就会出现对应的行或列。注意index_name
和col_name
可以是一个集合,即列表list,这样可以选出更复杂的数据样式。
print(df.loc['A', 'a']) # 1
print(df.loc['B', :])
'''
a 2
b 3
c 4
d 1
e 1
f 2
Name: B, dtype: object
'''
print(type(df.loc['B', :])) #
print(df.loc[:, 'd'])
'''
A *
B 1
C 1
D 7
Name: d, dtype: object
'''
print(df.loc[['A','C'], ['d','f']])
'''
d f
A * 2
C 1 3
'''
当然,Series
也可以变成list
。简单的说,一维可以直接取值作为列表元素 Series.tolist()
,二维的话就要取其中的数据,DataFrame.values.tolist()
。如果在这个过程中想要自定义的index
那就只有df.columns.tolist()
,在进行手动添加处理了。
按列的话主要是直接切片操作df[]
。按列的话,只会有取整列的情况,所以情况要简单些。
即在切片中放一个值或一个列表表示所筛选的列,在有些情况下,使用.col_name
能有很方便的操作。
print(df[['b','d']])
'''
b d
A 2 *
B 3 1
C 4 1
D 5 7
'''
将切片和.loc[]
结合起来,会有很多简单操作,但是建议不要太多依赖语法糖(假装)了,不然在记忆的时候会变得混乱,如下面的代码所示,在认为[]
是对列进行选取后,就尽量不要用它对行的操作(即传入一个布尔列表,它会对行进行选取)。
print(df.loc[df.f>2])
'''
a b c d e f
C 3 4 5 1 1 3
D 4 5 6 7 8 9
'''
print(df.f>2)
'''
A False
B False
C True
D True
Name: f, dtype: bool
'''
print(df[[False, False, True, True]])
'''
a b c d e f
C 3 4 5 1 1 3
D 4 5 6 7 8 9
'''
print(df[[False, False, False, False, False, True]])
'''
ValueError: Item wrong length 6 instead of 4.
'''
改
改的话无非就是,改索引;改属性;改数据。
对于改数据来说,就是赋值,我们能够找到任意行,任意列,所以赋值只需要传入对应行列的list
即可。
df.loc[['A','B'], ['a', 'b']] = [[3, 4], [5, 6]]
'''
a b c d e f
A 3 4 3 * * 2
B 5 6 4 1 1 2
C 3 4 5 1 1 3
D 4 5 6 7 8 9
'''
对于改属性来说,也可以用上述方法暴力,即df.columns = ['1', '2', '3', '4', '5', '6']
,此时要保证给的列表长度要与原来属性的长度相同。
采用.rename()
方法进行更改的话更加灵活,注意一定要指定传参的名字,inplace
如它的含义,是原地修改。
df.rename(columns = {"a":'g', 'c':'h'}, inplace = True)
'''
g b h d e f
A 3 4 3 * * 2
B 5 6 4 1 1 2
C 3 4 5 1 1 3
D 4 5 6 7 8 9
'''
对于改索引来说,也是.rename()
方法,所以这就是一定要指明传参名字的原因。
df.rename(index = {"A":'G', 'C':'H'}, inplace = True)
'''
g b h d e f
G 3 4 3 * * 2
B 5 6 4 1 1 2
H 3 4 5 1 1 3
D 4 5 6 7 8 9
'''
写在最后
其实pandas使用时,记住了以上常见的情况就能解决70%的问题,还有10%的问题是实际运用中,DataFrame对象在函数中传过来传过去时,对于原来的数据修改引发的问题,这相关的可以考虑参看copy
模块和python参数传递机制。