轩小陌的Python笔记-Pandas 数据处理

Pandas 数据处理

一、数据IO操作

pandas IO操作主要是读取和写入有特定格式的文件,如CSV文件、TXT文件:

# 本质上pd.read_csv和pd.read_tablepd.read_table的读取方式是一样的,区别只在于分隔符的不同
pd.read_csv('csv文件.csv', sep=',', header=None, index_col=0)

pd.read_table('txt文件.txt', header=None, sep=' ', index_col=0)

pd.read_csv('txt文件.txt', header=None, sep='-', index_col=0)

pd.read_csv('txt文件.txt', header=None, sep='\s+', index_col=0)	# 特别的,如果文件中的分隔符是数量不等的空格,则可以使用‘\s+’来分隔

# 写入文件
data.to_csv('m_data.csv')
data.to_txt('m_data.txt')

读写 excel 文件:

# names参数在pd.read_csv和pd.read_table中同样适用
# sheet_name=‘子表名’或sheet_name=0,1,2,3....(字表索引)
data = pd.read_excel('excel文件.xlsx', header=None, names=['姓名','年龄','地址'], sheet_name='Sheet1')

# 写入文件
data.to_excel('m_data.xlsx')

二、数据探索

describe()

df = pd.DataFrame(data=np.random.randint(0, 10000, size=(10000, 4)), columns=list('ABCD'))
print(df)
>>输出结果:
         A     B     C     D
0      235  5192   905  7813
1     2895  5056   144  4225
2     7751  3462  9394  5396
3     5374  2962  2516  8444
4     3562  4764  8093  6542
...    ...   ...   ...   ...
9995  1955  1727   214  8554
9996  7270   394  3708  9126
9997  5708  1119  2991  5106
9998  6006  9326  2398  9332
9999   582  1060  3400  2763
[10000 rows x 4 columns]


result1 = df.describe()
print(result1)
>>输出结果:
                  A            B             C             D
count  10000.000000  10000.00000  10000.000000  10000.000000
mean    4998.050200   5012.53500   4969.470800   5011.821100
std     2903.766726   2892.84581   2875.261794   2908.972103
min        0.000000      0.00000      2.000000      0.000000
25%     2435.750000   2473.75000   2490.750000   2485.000000
50%     5032.500000   5050.00000   4947.500000   5036.500000
75%     7542.000000   7505.00000   7481.250000   7513.250000
max     9998.000000   9999.00000   9999.000000   9999.000000

result2 = df.describe(percentiles=[0.99])
print(result2)
>>输出结果:
                  A            B             C             D
count  10000.000000  10000.00000  10000.000000  10000.000000
mean    4998.050200   5012.53500   4969.470800   5011.821100
std     2903.766726   2892.84581   2875.261794   2908.972103
min        0.000000      0.00000      2.000000      0.000000
50%     5032.500000   5050.00000   4947.500000   5036.500000
99%     9886.010000   9901.02000   9896.010000   9905.030000
max     9998.000000   9999.00000   9999.000000   9999.000000

result3 = df.describe(percentiles=[0.99]).T
print(result3)
>>输出结果:
     count       mean          std  min     50%      99%     max
A  10000.0  4998.0502  2903.766726  0.0  5032.5  9886.01  9998.0
B  10000.0  5012.5350  2892.845810  0.0  5050.0  9901.02  9999.0
C  10000.0  4969.4708  2875.261794  2.0  4947.5  9896.01  9999.0
D  10000.0  5011.8211  2908.972103  0.0  5036.5  9905.03  9999.0

info()

result = df.info()
print(result)
>>输出结果:
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 10000 entries, 0 to 9999
Data columns (total 4 columns):
 #   Column  Non-Null Count  Dtype
---  ------  --------------  -----
 0   A       10000 non-null  int32
 1   B       10000 non-null  int32
 2   C       10000 non-null  int32
 3   D       10000 non-null  int32
dtypes: int32(4)
memory usage: 156.4 KB

head()、tail()

result1 = df.head()
print(result1)
>>输出结果:
      A     B     C     D
0   235  5192   905  7813
1  2895  5056   144  4225
2  7751  3462  9394  5396
3  5374  2962  2516  8444
4  3562  4764  8093  6542

result2 = df.tail()
print(result2)
>>输出结果:
         A     B     C     D
9995  1955  1727   214  8554
9996  7270   394  3708  9126
9997  5708  1119  2991  5106
9998  6006  9326  2398  9332
9999   582  1060  3400  2763

result3 = df.tail(n=2)
print(result3)
>>输出结果:
         A     B     C     D
9998  6006  9326  2398  9332
9999   582  1060  3400  2763

sample()

result = df.sample(n=10)
print(result)
>>输出结果:
         A     B     C     D
8993  3251  4631  1932  2136
9753  7505  7822  4652  4019
6851  9831  2690  7266  5411
8044   141  5710  9001  2606
3594   951   297  9461  6519
7103   470  6780  1165  8743
3402  6804  1615  9748  1658
8361  2082  4687   868  9105
7230  9674  9832  3070  1007
9995  1955  1727   214  8554

三、空值处理

3.1 None和np.nan(NaN)

  • None是Python自带的,其类型为python object。因此,None不能参与到任何计算中。object类型的运算要比float类型的运算慢得多。

  • np.nan是浮点类型,能参与到计算中。但计算的结果总是NaN。在numpy中,可以使用np.nanxxx()函数来计算nan,此时视nan为0。

print(type(None))
>>输出结果:
NoneType

print(type(np.nan))
>>输出结果:
float

def get_sum(x):
    return x.sum()

data1 = np.arange(1000000, dtype=object)
%timeit get_sum(data1)
>>输出结果:
23.2 ms ± 708 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)

data2 = np.arange(1000000, dtype=np.float)
%timeit get_sum(data2)
>>输出结果:
1.21 ms ± 62.9 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

3.2 pandas自动把None处理成np.nan

  • np.nan 是 numpy 提供的一个常量,用于表达空值,是一个float类型。

  • NaN(not a number) 是一个符号,不是一个常量, pandas对象中,所有的 np.nan 和 None 显示的时候,都是以NaN显示。类似的还有NaT (not a time)。

df = pd.DataFrame(data=np.random.randint(0, 10, size=(10, 2)), columns=['A','B'])
print(df)
>>输出结果:
    A	B
0	5	1
1	2	0
2	9	6
3	2	8
4	5	8
5	4	3
6	4	1
7	5	5
8	0	7
9	0	6

df.loc[2] = None
print(df)
>>输出结果:
	 A	 B
0	5.0	1.0
1	2.0	0.0
2	NaN	NaN
3	2.0	8.0
4	5.0	8.0
5	4.0	3.0
6	4.0	1.0
7	5.0	5.0
8	0.0	7.0
9	0.0	6.0

3.3 空值查找

isnull()、notnull()

df = pd.DataFrame(data=np.random.random(size=(10, 4)), columns=list('ABCD'))
df.loc[2] = np.nan
df.loc[4, 'B'] = np.nan
df.loc[5, 'D'] = np.nan
df.loc[9, ['A','B']] = np.nan
print(df)
>>输出结果:

       A	       B	       C	       D
0	0.726244	0.078825	0.239853	0.870938
1	0.961002	0.205138	0.678396	0.366292
2	NaN	        NaN	        NaN	        NaN
3	0.820113	0.575757	0.302384	0.817682
4	0.897944	NaN	        0.427351	0.036945
5	0.888940	0.932362	0.494705	NaN
6	0.056371	0.410048	0.992545	0.828778
7	0.431613	0.260433	0.779346	0.851420
8	0.325942	0.721456	0.177086	0.440415
9	NaN	        NaN	        0.150183	0.720072

result1 = df.isnull().any()		# 默认列方向的any操作
print(result1)
>>输出结果:
A    True
B    True
C    True
D    True
dtype: bool

result2 = df.isnull().any(axis=1)
print(result2)
>>输出结果:
0    False
1    False
2     True
3    False
4     True
5     True
6    False
7    False
8    False
9     True
dtype: bool

# 找出所有包含至少一个空值的行
result3 = df.loc[df.isnull().any(axis=1)]
print(result3)
>>输出结果:
    A	        B	        C	        D
2	NaN	        NaN	        NaN	        NaN
4	0.295703	NaN	        0.233566	0.557783
5	0.168698	0.298293	0.674066	NaN
9	NaN	        NaN	        0.905542	0.187831

# 找出全都不为空的行
result4 = df.loc[df.notnull().all(axis=1)]
print(result4)
>>输出结果:
    A	        B			C			D
0	0.971378	0.695311	0.453382	0.028843
1	0.081022	0.380908	0.161295	0.464460
3	0.321058	0.541224	0.456106	0.680896
6	0.965566	0.084760	0.107426	0.056833
7	0.195171	0.938648	0.759900	0.683615
8	0.197814	0.516687	0.076623	0.009585

# 查看某一列的空值占比
result5 = df.isnull().mean()
print(result5)
>>输出结果:
A    0.2
B    0.3
C    0.1
D    0.2
dtype: float64

3.4 空值填充

  • 整个表格中的统一填充方法

    df.fillna(value=0)
    
  • 使用均值来填充空值

    df.fillna(value=df.mean())
    
  • 使用临近值填充,不需要再指定value

    df.fillna(method='backfill', axis=1)
    df.fillna(method='ffill', axis=1,limit=1)
    

3.5 空值过滤

  • 结合isnull、notnull、any all 来确定一个条件,然后再利用loc访问,实现过滤

    df.loc[df.notnull().any(axis=1)]
    
  • dropna()

    df.dropna(axis=0, how='any')
    
    df.dropna(axis=0, how='all', subset=['B','A'], inplace=True)
    

四、异常值处理

体育比赛里,最后算分的时候总会去掉一个最高分,去掉一个最低分,将剩下的分数进行去平均。因为一个非常夸张的异常值可能会造成对最后统计结果产生比较大的影响。所以,异常值处理,在统计数据的过程中是必然要做的一个操作。

4.1 异常值分析

使用describe()函数查看每一列的描述性统计量

4.2 处理异常值

  • 不符合业务逻辑的异常值

    cond  = df['关注字段'] != '关注的内容'
    df.loc[cond]
    
  • 使用均值和标准差进行判断

    df = pd.DataFrame(data=np.random.randn(10000, 4), columns=list('ABCD'))
    
    # 异常值判断条件
    exp_condition = (np.abs(df) > df.std()*3).any(axis=1)
    # 获取异常值对应的索引
    exp_index = df.loc[exp_condition].index
    # 删除异常值对应索引的值
    df1 = df.drop(labels=exp_index, axis=0)
    
  • 使用上四中位数和下四中位数进行异常值判定

    order = pd.read_excel('电商用户数据.xlsx')
    order.info()
    >>输出结果:
    <class 'pandas.core.frame.DataFrame'>
    RangeIndex: 28833 entries, 0 to 28832
    Data columns (total 8 columns):
    买家昵称    28833 non-null object
    付款日期    28833 non-null datetime64[ns]
    订单状态    28833 non-null object
    实付金额    28833 non-null int64
    邮费      28833 non-null int64
    省份      28833 non-null object
    城市      28832 non-null object
    购买数量    28833 non-null int64
    dtypes: datetime64[ns](1), int64(3), object(4)
    memory usage: 1.8+ MB
    
    order.describe(percentiles=[.99])
    >>输出结果:
    			 实付金额			邮费	   购买数量
    count	28833.000000 28833.000000 28833.000000
    mean	126.266570		 0.245240	  1.510942
    std		73.771696		 1.386435	  1.483478
    min		30.000000		 0.000000	  1.000000
    50%		115.000000		 0.000000	  1.000000
    99%		269.000000		 8.000000	  6.000000
    max		4225.000000		18.000000	100.000000
    
    
    Q1, Q3 = np.quantile(order['实付金额'], q=[0.25, 0.75])
    IQR = Q3 - Q1
    BOTTOM = Q1 - 1.5*IQR
    UPPER = Q3 + 1.5*IQR
    
    condition = (order['实付金额'] > UPPER).values | (order['实付金额'] < BOTTOM).values
    exp_index = order.loc[condition].index
    order.drop(index=exp_index).describe()
    >>输出结果:
    			 实付金额			  邮费		 购买数量
    count	28811.000000	28811.000000	28811.000000
    mean	  125.846656		0.245427		1.491444
    std		   68.639111		1.386947		1.072723
    min		   30.000000		0.000000		1.000000
    25%		   72.000000		0.000000		1.000000
    50%		  114.000000		0.000000		1.000000
    75%		  178.000000		0.000000		2.000000
    max		  336.000000       18.000000	   20.000000
    

五、重复值处理

df = pd.DataFrame(data=np.random.randint(0, 100, size=(10,5)), columns=list('abcde'))
df.loc[2] = df.loc[6]
df.loc[3] = df.loc[7]
df.loc[8] = df.loc[7]
df.loc[2, 'a'] = 100
print(df)
>>输出结果:
	a	b	c	d	e
0	82	63	48	90	25
1	84	52	55	38	6
2	100	81	48	12	22
3	17	95	19	22	81
4	61	8	95	17	93
5	13	56	64	78	59
6	20	81	48	12	22
7	17	95	19	22	81
8	17	95	19	22	81
9	11	10	99	95	54

# 检查
condition = df.duplicated(keep='last', subset=list('bcde'))
# keep:保留首次出现的重复值first还是最后一次出现的重复值last
# subse:指定,用来判断重复值的列索引
>>输出结果:
0    False
1    False
2     True
3     True
4    False
5    False
6    False
7     True
8    False
9    False
dtype: bool

# 过滤
df.loc[(condition - 1).astype(bool)]
>>输出结果:
	a	b	c	d	e
0	82	63	48	90	25
1	84	52	55	38	6
4	61	8	95	17	93
5	13	56	64	78	59
6	20	81	48	12	22
8	17	95	19	22	81
9	11	10	99	95	54

# 删除
df.drop_duplicates(subset=list('bcde'), keep='last',)
>>输出结果:
	a	b	c	d	e
0	82	63	48	90	25
1	84	52	55	38	6
4	61	8	95	17	93
5	13	56	64	78	59
6	20	81	48	12	22
8	17	95	19	22	81
9	11	10	99	95	54

六、Pandas排序与随机抽样

排序

df1 = df.sort_values(by='a', ascending=False)
print(df1)
>>输出结果:
	a	b	c	d	e
2	100	81	48	12	22
1	84	52	55	38	6
0	82	63	48	90	25
4	61	8	95	17	93
6	20	81	48	12	22
3	17	95	19	22	81
7	17	95	19	22	81
8	17	95	19	22	81
5	13	56	64	78	59
9	11	10	99	95	54

# 指定多条件排序
df2 = df.sort_values(by=['b','a'], ascending=True)
print(df2)
>>输出结果:
	a	b	c	d	e
4	61	8	95	17	93    
9	11	10	99	95	54
1	84	52	55	38	6
5	13	56	64	78	59
0	82	63	48	90	25
6	20	81	48	12	22
2	100	81	48	12	22
3	17	95	19	22	81
7	17	95	19	22	81
8	17	95	19	22	81

df3 = df2.sort_index(ascending=False)
print(df3)
>>输出结果:
	a	b	c	d	e
9	69	16	67	25	89
8	4	19	2	56	0
7	4	19	2	56	0
6	60	52	51	15	13
5	19	8	60	96	55
4	82	48	54	68	5
3	4	19	2	56	0
2	100	52	51	15	13
1	80	87	26	82	15
0	20	96	63	93	23

随机取出行或列

df1 = df.sample(n=3, axis=1)
print(df1)
>>输出结果:
	d	b	a
0	93	96	20
1	82	87	80
2	15	52	100
3	56	19	4
4	68	48	82
5	96	8	19
6	15	52	60
7	56	19	4
8	56	19	4
9	25	16	69

df2 = df.take([1,1,2,2,3,3], axis=1)
print(df2)
>>输出结果:
	b	b	c	c	d	d
0	96	96	63	63	93	93
1	87	87	26	26	82	82
2	52	52	51	51	15	15
3	19	19	2	2	56	56
4	48	48	54	54	68	68
5	8	8	60	60	96	96
6	52	52	51	51	15	15
7	19	19	2	2	56	56
8	19	19	2	2	56	56
9	16	16	67	67	25	25

七、索引设置

把指定字段设置为索引

df1 = df.set_index(keys=['a','b'])
print(df1)
>>输出结果:
		c	d	e
a	b			
20	96	63	93	23
80	87	26	82	15
100	52	51	15	13
4	19	2	56	0
82	48	54	68	5
19	8	60	96	55
60	52	51	15	13
4	19	2	56	0
19	2	56	0
69	16	67	25	89

把指定索引设置为字段

df2 = df1.reset_index(level=-1)
print(df2)
>>输出结果:
	b	c	d	e
a				
20	96	63	93	23
80	87	26	82	15
100	52	51	15	13
4	19	2	56	0
82	48	54	68	5
19	8	60	96	55
60	52	51	15	13
4	19	2	56	0
4	19	2	56	0
69	16	67	25	89

按照指定的索引,进行索引重置(如果原始索引中存在,则选择,如果不存在,则空值填充)

df3 = df2.reindex(labels=['b','c','d','f'], axis=1)
print(df3)
>>输出结果:
	b	c	d	f
a				
20	96	63	93	NaN
80	87	26	82	NaN
100	52	51	15	NaN
4	19	2	56	NaN
82	48	54	68	NaN
19	8	60	96	NaN
60	52	51	15	NaN
4	19	2	56	NaN
4	19	2	56	NaN
69	16	67	25	NaN

多层索引的删除

df4 = df1.droplevel(level=-1,axis=0)	# level:指定要删除的索引层级

八、映射处理

rename

df.rename(mapper=lambda x: str(x)+'产品', axis=1)
>>输出结果:

  	a产品 b产品	c产品	d产品	e产品
0	20	 96	   63	93	  23
1	80	 87	   26	82	  15
2	100	 52	   51	15	  13
3	4	 19	   2	56	  0
4	82	 48	   54	68	  5
5	19	 8	   60	96	  55
6	60	 52	   51	15	  13
7	4	 19	   2	56	  0
8	4	 19	   2	56	  0
9	69	 16	   67	25	  89


dic = {'a':'A', 'b':'B', 1:'HHH', 2:'GGG'}
df.rename(index=dic)
>>输出结果:
	a	b	c	d	e
0	20	96	63	93	23
HHH	80	87	26	82	15
GGG	100	52	51	15	13
3	4	19	2	56	0
4	82	48	54	68	5
5	19	8	60	96	55
6	60	52	51	15	13
7	4	19	2	56	0
8	4	19	2	56	0
9	69	16	67	25	89

df.rename(columns=dic)
>>输出结果:
	A	B	c	d	e
0	20	96	63	93	23
1	80	87	26	82	15
2	100	52	51	15	13
3	4	19	2	56	0
4	82	48	54	68	5
5	19	8	60	96	55
6	60	52	51	15	13
7	4	19	2	56	0
8	4	19	2	56	0
9	69	16	67	25	89

replace

df = pd.DataFrame(data=np.random.randint(0,100,size=(5,4)), columns=list('ABCD'))
>>输出结果:
	A	B	C	D
0	43	92	1	15
1	15	61	77	2
2	13	24	8	83
3	73	4	60	7
4	96	92	80	77

# list替换
df.replace(to_replace=[73, 77], value=['hello', 'hello world'], inplace=True)
>>输出结果:

	A	B	C	D
0	43	92	1	15
1	15	61	hello world	2
2	13	24	8	83
3	hello	4	60	7
4	96	92	80	hello world

# dict替换
df.replace(to_replace={83:'hehe', 43:'good'}, inplace=True)
>>输出结果:
	A		B	C			D
0	good	92	1			15
1	15	    61	hello world	2
2	13		24	8			hehe
3	hello	4	60			7
4	96		92	80			hello world

# 特殊用法:指定列替换。字典的键是列名称,字典的值是该列里面的要替换的值
df.replace(to_replace={'A':'hello'}, value='hELLO')
>>输出结果:
	A		B	C			D
0	good	92	1			15
1	15	    61	hello world	2
2	13		24	8			hehe
3	hELLO	4	60			7
4	96		92	80			hello world

# regex替换
df.replace(to_replace=r'h.*',value='H',regex=True, inplace=True)
>>输出结果:
	A	 B	 C	 D
0	good 92	 1	 15
1	15	 61	 H	 2
2	13   24	 8	 H
3	H	 4	 60  7
4	96	 92	 80	 H

# 相邻值替换
df.replace(to_replace='H', method='bfill', limit=1)
>>输出结果:
	A	 B	 C	 D
0	good 92	 1	 15
1	15	 61	 2	 2
2	13   24	 8	 H
3	4	 4	 60  7
4	96	 92	 80	 H

map,支持Series对象

D = df['B']
>>输出结果:
0    92
1    61
2    24
3     4
4    92
Name: B, dtype: int64

# 模糊匹配
def score_map(x):
    if x >= 60:
        return '及格'
    else:
        return '不及格'

D_re = D.map(score_map)
print(D_re)
>>输出结果:
0     及格
1     及格
2    不及格
3    不及格
4     及格
Name: B, dtype: object

# 精确匹配
map_dic = {
    '及格':True,
    '不及格':False
}
D_re.map(map_dic)
>>输出结果:
0     True
1     True
2    False
3    False
4     True
Name: B, dtype: bool
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值