guxh

创建df:

>>> 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

通过行名称删除:

df = df.drop([\'1\', \'2\'])           # 不指定axis默认为0
df.drop([\'1\', \'3\'], inplace=True)

通过行号删除:

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,通过各种筛选方法实现删除行

详见pandas“选择行单元格,选择行列“的笔记

举例,通过筛选可以实现很多功能,例如要对某行数据去重,可以获取去重后的index列表后,使用loc方法:

>>> 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
>>> df.loc[chooses]
    A   B   C   D
1   0   1   2   3
2   4   9   6   7
4  12  13  14  15 

 

2,删除列

2.1,del

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

 

2.2,drop

通过列名称删除:

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

使用列数删除,传入参数是int,列表,者切片:

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列

 

2.3,通过各种筛选方法实现删除列

详见pandas“选择行单元格,选择行列“的笔记

 

3,增加行

3.1,loc,at,set_value

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

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)    # warning,set_value会被取消

 

3.2,append

添加有name的Series: 

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

添加没有name的Series,必须ignore_index:

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

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

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

  

3.3,逐行增加

简单的逐行添加内容,可以:

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

但需要注意:len(df)生成的是int,如果生成的int,df已经存在了,会覆盖该行数据,而不会新增

 

3.4,插入行

增加行没找到类似insert这种可以插入的方法,暂时替代方法可以先reindex,再赋值:

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

 

 

4,df增加列

一般涉及到增加列项时,经常会对现有的数据进行遍历运算,获得新增列项的值,所以这里结合对DataFrame的遍历讨论增加列。

例如,想增加一列\'E\',值等于\'A\'和\'C\'列对应值之和。

4.1,遍历DataFrame获取序列的方法

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矢量相加获取序列

  

4.2,[ ],loc

通过df[]或者df.loc添加序列

df.loc[:, \'E\'] = s
df[\'E\'] = s

 

4.3,Insert

可以指定插入位置,和插入列名称

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

 

4.4,concat

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

  

4.5,iloc和loc遍历过程中给列赋值

效率比较低

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

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:

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列赋空值:

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

 

4.6,逐列增加

简单的逐列添加内容,可以:

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

但需要注意:len(df)生成的是int,如果生成的int,df已经存在了,会覆盖该列数据,而不会新增

 

4.7,其他方法

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

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

 

 
 
 
 

分类:

技术点:

相关文章: