0%

Pandas最基础的操作

tmd,用惯了r,开始用Python pandas,每一步我都知道要干啥,就是不知道要怎么做,太烦了!!我来把最基础的操作系统学习一下,记在这里备忘:

0. 创建df:

1
2
3
4
5
6
7
>>> df = pd.DataFrame(np.arange(16).reshape(4, 4), columns=list('ABCD'), index=list('1234'))
>>> df
A B C D
1 0 1 2 3
2 4 5 6 7
3 8 9 10 11
4 12 13 14 15

1. 删除行列

1.1. drop删除行列

inplace=True 表示就地修改,如果不设置,则会创建副本返回

通过行名删除:

1
2
df =df.drop(['1', '2'])      # 不指定axis默认为0, 即“行”
df.drop(['1', '3'], inplace=True) # inplace=True 就地修改

通过行号删除,传入参数是int、列表或切片:

1
2
3
df.drop(df.index[0], inplace=True)    # 删除第1行
df.drop(df.index[0:3], inplace=True) # 删除前3行
df.drop(df.index[[0, 2]], inplace=True) # 删除第1第3行

通过列名删除:

1
2
df = df.drop(['B', 'C'], axis=1)               # drop不会就地修改,创建副本返回
df.drop(['B', 'C'], axis=1, inplace=True)

通过列号删除:

1
2
3
df.drop(df.columns[0], axis=1, inplace=True)       # 删除第1列
df.drop(df.columns[0:3], axis=1, inplace=True) # 删除前3列
df.drop(df.columns[[0, 2]], axis=1, inplace=True) # 删除第1第3列

1.2. 去重

1
2
3
4
5
6
7
8
9
10
11
12
13
>>> df.loc['2','B']=9
>>> df
A B C D
1 0 1 2 3
2 4 9 6 7
3 8 9 10 11
4 12 13 14 15
>>> chooses = df['B'].drop_duplicates().index # B列删除重复行后的索引
>>> df.loc[chooses] # 删除B列重复的行
A B C D
1 0 1 2 3
2 4 9 6 7
4 12 13 14 15

1.3. del删除列

1
del df['A']  # 删除A列,会就地修改

2. 增加行

2.1. loc / at / set_value

想增加一行,行名为'5',内容为[16, 17, 18, 19]

1
2
3
df.loc['5'] = [16, 17, 18, 19]    # 后面的序列是Iterable就行
df.at['5'] = [16, 17, 18, 19]
df.set_value('5', df.columns, [16, 17, 18, 19], takeable=False) # 过时

2.2. append

添加有name的Series:

1
2
s = pd.Series([16, 17, 18, 19], index=df.columns, name='5')
df = df.append(s)

添加没有name的Series,必须ignore_index

1
2
s = pd.Series([16, 17, 18, 19], index=df.columns)
df = df.append(s, ignore_index=True)

可以 append字典列表,同样需要必须ignore_index:

1
2
ls = [{'A': 16, 'B': 17, 'C': 18, 'D': 19}, {'A': 20, 'B': 21, 'C': 22, 'D': 23}]
df = df.append(ls, ignore_index=True)

2.3. df.loc[行号] = [x,x,x]

1
df.loc[len(df)] = [16, 17, 18, 19]

len(df)生成的是最后一行行数,正好表示在最后一行增加。如果选择已经存在的行,会覆盖该行数据

2.4. 插入行

没有类似insert的方法,暂时替代方法可以先用reindex在行索引中增加一个索引,再给该索引对应的行赋值:

1
2
df = df.reindex(index=df.index.insert(2, '5'))
df.loc['5'] = [16, 17, 18, 19]

3. 增加列

序列s = 列A+列C的5种方法:

1
2
3
4
5
s = [a + c for a, c in zip(df['A'], df['C'])]          
s = [row['A'] + row['C'] for i, row in df.iterrows()] # 通过iterrows()获取序列,s为list
s = df.apply(lambda row: row['A'] + row['C'], axis=1) # 通过apply获取序列,s为Series
s = df['A'] + df['C'] # 通过Series矢量相加获取序列
s = df['A'].values + df['C'].values # 通过Numpy矢量相加获取序列

3.1. df[]或者df.loc

1
2
df.loc[:, 'E'] = s
df['E'] = s

3.2. df.insert()

1
df.insert(0, 'E', s) 

3.3. pd.concat()

1
2
s = pd.Series([16, 17, 18, 19], name='E', index=df.index)
df = pd.concat([df, s], axis=1)

3.4. iloc和loc遍历过程中给列赋值

效率比较低

df['E']是DataFrame的一个Series,是引用,对其修改也能改变DataFrame,但运行时报了Warning

1
2
3
4
df['E'] = None  # 需事先创建e列,否则iloc遍历会报错,loc遍历无需事先创建
for i in range(len(df)):
df['E'].iloc[i] = df['A'].iloc[i] + df['C'].iloc[i]
# SettingWithCopyWarning: A value is trying to be set on a copy of a slice from a DataFrame

不用Series不会报Warning:

1
2
3
4
df['E'] = None
col_no = [i for i in df.columns].index('E')
for i in range(len(df)):
df.iloc[i, col_no] = df['A'].iloc[i] + df['C'].iloc[i]

用loc无需先给E列赋空值:

1
2
for i in df.index:
df.loc[i, 'E'] = df.loc[i, 'A'] + df.loc[i, 'C']

3.5. df[列号] = [x,x,x]

1
df[len(df)] = [16, 17, 18, 19]

3.6. 其他方法

增加3列,EFG,value默认为np.NaN

1
2
df = pd.concat([df, pd.DataFrame(columns=list('EFG'))])   # 列的次序无法指定,并且fillna时会对整个df做出调整
df = df.reindex(columns=list('ABCDEFG'), fill_value=0) # 列的次序按照list指定,并且fill_value只对新增列做出调整,推荐!

4. 修改行列

1
2
3
4
5
6
7
# loc和iloc 可以更换单行、单列、多行、多列的值
df1.loc[0,'age']=25 # 思路:先用loc找到要更改的值,再用赋值(=)的方法实现更换值
df1.iloc[0,2]=25 # iloc:用索引位置来查找

# at 、iat只能更换单个值
df1.at[0,'age']=25 # iat 用来取某个单值,参数只能用数字索引
df1.iat[0,2]=25 # at 用来取某个单值,参数只能用index和columns索引名称

5. dataFrame拼接

1
pd.concat([data1, data2], axis=0)

第一个参数放入的是我们要拼接的数据,记住当有多组数据时,必须要用[]括起来,让其变为一个整体(因为这个参数只占一个位置,不加会抛出错误)

axis参数:用来设置拼接方式(0-从下方纵向增加记录;1-从右侧增加字段),其中axis=0为默认值

6. 改列名

1、修改列名a,b为A、B。

1
df.columns = ['A','B']

2、只修改列名a为A

1
df.rename(columns={'a':'A'}, inplace = True)

其他发布渠道