python数据分析最常用操作总结

【学习、工作总结】自己使用python进行数据分析的过程中最常用到的一些操作,进行一个归纳化总结,会对该文档进行持续性更新,主要可能更新常用的函数,希望能对你有所帮助。

1.数据预处理常用操作

 1.1 字段值的切片

  1.1.1 常见数据类型的切片

  基本切片语法为sequence[start:end:step],三个参数分别代表起始位置(默认0)、结束位置、步长(默认为1),无论是字符串、列表或者,元组都可以使用这种方式进行切片。
需要注意的是start参数是包含起始位置,end是不包含表示的结束位置的
以字符串为例:

string = "Hello,World!"
# 结束位置为5,但是从0开始,因此是提取前5个字符
substring = string [:5]
print(substring)  # 输出:Hello

#输出后5个字符
substring = string [-5:]
print(substring)  # 输出:orld!

# 从第7个字符开始到倒数最后一个字符(不包含)
substring = string [6:-1]
print(substring)  # 输出:World

# 每隔两个字符取一个
substring = string [::2]
print(substring)  # 输出:HloWrd

  1.1.2 dataframe表的切片

现有pandas中dataframe格式的数据如下:

FruitPrice
apple¥10/kg
banana¥8/kg

现我要将Price列的数据变为纯数字以便计算,需要对该列进行切片。同样也可以使用.str.slice[,]进行切片。

df['Price'] = df['Price'].astype(str).str[1:-3]

使用该代码会直接在原始Price列上修改数据。
若需要将切片后的数据直接变成数据框的新列,直接在等号左边改列名即可,pandas会自动生成新的一列

#转化为字符串后直接进行索引切片
df['PriceNumber'] = df['Price'].astype(str).str[1:-3]
#使用str.slice,功能一样,但如果该列不是字符串类型会报错。
df['PriceNumber'] = df['Price'].str.slice[1:-3]

FruitPricePriceNumber
apple¥10/kg10
banana¥8/kg8

切片的逻辑和上文一样也是三个参数,但是在切数据框时需要注意的是:
  在 Pandas 中,只有字符串类型的 Series 对象才能使用 .str ()属性进行字符串操作,而整数类型的 Series 对象没有该属性。因此,如果不先使用.astype(str)将列转换为字符串类型,就无法直接在使用字符串的切片操作。可能会出现报错AttributeError: 'Series' object has no attribute 'str'
  切片操作返回的是一个 Series 对象,可以进一步对该 Series 对象进行操作或转换为其他数据结构。

 1.2 类型判断与转换

  检查数据的类型通常有好几种方法,最常用的即是使用.type(对象名)判断数据的类型。
  如果在pandas中,需要检查每一列的数据类型,可以使用.dtype()来检查各列数据的类型,返回的是Series类型。
  还可以利用函数isinstance()对数据类型进行判断,该接受两个参数,第一个是待检查的对象,第二个是要检查的类型。如果对象属于所指定的类型之一,则返回 True;否则返回 False。

import pandas as pd

data = {
    'A': [1, 2, 3],
    'B': ['foo', 'bar', 'baz'],
    'C': [True, False, True]
}

df = pd.DataFrame(data)

print(df.dtypes)

返回结果为:

A      int64
B     object
C       bool
dtype: object

如果使用isinstance()对类型进行判断,代码如下

import pandas as pd

data = [1, 2, 3, 4, 5]
series = pd.Series(data)

print(isinstance(series, pd.Series))  # 输出:True

  1.2.1 基本数据类型间的相互转换

    ①基础数据类型间的数据转换可以直接用内置函数,下面是一些常见函数:
      int(): 将一个对象转换为整数类型。
      float(): 将一个对象转换为浮点数类型。
      str(): 将一个对象转换为字符串类型。
      bool(): 将一个对象转换为布尔类型。
      tuple(): 将一个对象转换为元组类型。
      dict(): 将一个对象转换为字典类型。

x = 5

# 将整数转换为浮点数
y = float(x)
print(y)  # 输出:5.0

# 将整数转换为字符串
z = str(x)
print(z)  # 输出:'5'

# 将整数转换为布尔值
a = bool(x)
print(a)  # 输出:True

    转换成布尔数据类型时,如果原始数据是数值型(整数、浮点),则非0为True,0为False。如果是字符型数据或者其他基本数据类型(列表、元组、集合),则非空为True,空为False
    ②.format()函数也可以进行格式的转换,

# 对插入的值进行格式化
number = 3.1415926
formatted_string = "pi is approximately {:.2f}.".format(number)
print(formatted_string)  # 输出:pi is approximately 3.14.

  1.2.2 DataFrame以及经各种函数处理后的Series类型的转换

    ①若是pandas中dataframe数据类型的转换,可用.astype()具体对数据表的每一列数据进行转换。

df['A'] = df['A'].astype(float)#将df的A列转换为浮点类型

    ②时间格式的数据转换,时间格式的日期转换通常用到函数to_datetime().dt.strftime()函数。

# 将 Date 列转换为日期时间类型
df['Date'] = pd.to_datetime(df['Date'])
print(df.dtypes)

# 将 Date 日期列转换为字符串类型
df['Date'] = df['Date'].dt.strftime('%Y-%m-%d')
print(df.dtypes)

  在利用pandas进行数据分析时,数据类型的报错是常见的错误。dataframe在经过pandas函数处理后,大部分都是变成了Series类型,而Series类型有部分函数是不能调用的。
  另一个常见问题则是维度的问题。在 Pandas 中,可以使用 .reshape() 方法来重新构造 DataFrame 和 Series 的数据形状。.reshape() 方法用于调整数组的维度。

import pandas as pd
import numpy as np

# 示例 1:对 Series 使用 .reshape()
s = pd.Series([1, 2, 3, 4, 5, 6])
print(s.shape)                  # 输出:(6,)
reshaped_s = s.reshape((2, 3))
print(reshaped_s.shape)         # 输出:(2, 3)
print(reshaped_s)
# 输出:
# [[1 2 3]
#  [4 5 6]]

# 示例 2:对 DataFrame 使用 .reshape()
df = pd.DataFrame({'A': [1, 2, 3], 'B': [4, 5, 6]})
print(df.shape)                 # 输出:(3, 2)
reshaped_df = df.values.reshape((2, 3))
print(reshaped_df.shape)        # 输出:(2, 3)
print(reshaped_df)
# 输出:
# [[1 2 3]
#  [4 5 6]]

  在 Pandas 中.squeeze()方法用于将数据结构维度中大小为 1 的维度进行压缩。该方法适用于 Series 或 DataFrame 对象。当使用 .squeeze() 方法时,如果数据结构的某个维度只有一个元素,那么该维度会被挤压并且返回一个维度更低的对象。如果维度大于 1,那么对象不会发生任何变化。

import pandas as pd

# 示例 1:对 Series 使用 .squeeze()
s = pd.Series([1, 2, 3])
print(s.shape)      # 输出:(3,)
print(s.squeeze())  # 输出:[1 2 3]

# 示例 2:对 DataFrame 使用 .squeeze()
df = pd.DataFrame({'A': [1], 'B': [2]})
print(df.shape)    # 输出:(1, 2)
print(df.squeeze())  # 输出:
#   A    1
#   B    2
#   Name: 0, dtype: int64

 1.3 行与列的删除与提取

  1.3.1 基本数据类型行列的删除与提取

  元组一旦创建就不能进行删除,但可以通过索引来生成一个新的元组对象,索引的方式与上文切片方法一样。列表一般也是通过索引的方式来进行删除或者提取。

# 示例列表
my_list = [['a', 'b', 'c'],
           ['d', 'e', 'f'],
           ['g', 'h', 'i'],
           ['j', 'k', 'l']]

# 提取第一行和第三行
rows_1_3 = my_list[0:3:2]
print(rows_1_3)  # 输出:[['a', 'b', 'c'], ['g', 'h', 'i']]
#列表要在原来基础上提取的话,把rows_1_3改成列表名即my_list即可达到效果


# 若我要单独删除第二行,直接使用del即可达到效果
del my_list[1]
print(my_list)  # 输出:[['a', 'b', 'c'], ['g', 'h', 'i'], ['j', 'k', 'l']]

  del一次只能删除一行,因此如果要对列表一次性删除多行,可使用循环进行遍历,在这个循环中,使用reversed()的作用是从后面开始删除,这样前面行的索引才不会变。比如我要删除索引为0,2的行,如果先删除索引为0的,原本索引为2的行就变成了1。
若你的删除行的索引是[2,0],本来就是从后往前,那就可以直接for index in rows_to_delete:

# 删除第一行和第三行
rows_to_delete = [0, 2]  # 要删除的行的索引

for index in reversed(rows_to_delete):
    del my_list[index]

print(my_list)  # 输出:[['d', 'e', 'f'], ['j', 'k', 'l']]

  或者你也可以用直接重新索引生成的方式,enumerate() 函数获取每行的索引值组合条件语句也可以达到一样的效果:

# 把需要的行直接加,变相相当于删除第一行和第三行
my_list = my_list[1:2] + my_list[3:]

# 删除第一行和第三行,条件语句,判断行的索引
my_list = [row for idx, row in enumerate(my_list) if idx != 0 and idx != 2]

  使用pop()方法可以删除字典指定键对应的键值对,并返回该键对应的值。因此下面代码中deleted_value 返回的值是8

#示例字典
my_dict = {'Fruit': 'apple', 'price': '8 元/kg', 'pricenumber': '8'}


print (my_dict) # 输出整个字典
print (my_dict['Fruit']) # 输出键为'Fruit' 的值:apple
print (my_dict.keys()) # 输出所有键
print (my_dict.values()) # 输出所有值

# 删除指定键对应的行
deleted_value = my_dict.pop('pricenumber')
print(deleted_value)  # 输出:8
print(my_dict)  # 输出:{'Fruit': 'apple', 'price': '8 元/kg'}

  1.3.2 DataFrame透视表行列的删除与提取

   ①行列的提取

     要提取 DataFrame 中的一列,可以直接使用列名作为索引。提取的结果将是一个 Series 对象。

import pandas as pd

# 提取 'Price' 列
name_column = df['Price']
print(name_column)

   而如果使用loc()iloc()进行索引提取,则返回的对象是一个子dataframe对象,因此实际使用时,使用这两个进行索引会比较多,可以省去格式转换的一步。
   这两个函数的区别是loc()是基于标签进行索引和选择,而 iloc() 是基于位置进行索引和选择。因此,使用 loc() 时,可以通过标签选择数据,而使用 iloc() 时,需要使用整数位置来选择数据。

另外,loc 支持对数据进行切片时包含末端索引,而 iloc 不包含末端索引。

# 使用 loc 通过标签选择数据,选择从行标签 0 到 1(包括)和列标签 'Fruit' 到 'Price'(包括)的数据。
selected_data = df.loc[0:1,'Fruit':'Price']
print(selected_data)

# 使用 iloc 通过位置选择数据
selected_data = df.iloc[0:2, 0:2]#不包含索引为2的行和列
print(selected_data)

  这两端代码最后都是输出df矩阵左上角2X2的新矩阵,','前表示行的索引,后表示对列的索引

   ②行列的删除

  可以使用drop()函数,axis=1表示删除列,axis=0则表示删除行,默认为0

df = df.drop('PriceNumber', axis=1)#删除掉PriceNumber列
print(df)

#同样,del也可以直接删除单列
del df['PriceNumber']

  若要删除某一行,首先可以通过索引直接删除,或者按符合某条件的删除

df = df[df['PriceNumber'] != 8]#按条件删除PriceNumber列=8的所有行

# 按索引删除第4,10,20行
rows_to_delete = [3, 9, 19]  # 要删除的行的索引

df = df.drop(rows_to_delete).reset_index(drop=True)#这里reset_index的作用是充值索引,以保证前面的行删除后,后面的索引不会变。

 1.4 缺失值处理

   1.4.1 缺失行或列的删除

  在数据处理过程中,若要删除缺失行,可以直接用上文中教的方式按索引进行删除,也可以直接使用dropna()函数进行删除。

import pandas as pd

# 创建包含缺失值的示例 DataFrame
data = {'A': [1, 2,None, 4],
        'B': [5,None, 7, 8],
        'C': [None, 10, 11, 12]}
df = pd.DataFrame(data)

# 删除包含缺失值的行,axis=0表示删除行,axis=1表示删除列
df_dropped = df.dropna(axis=0)
print("删除缺失值的行:")
print(df_dropped)

  在实际数据处理过程中,基本要该列数据的缺失值大于40%以上,才会考虑进行删除

# 计算每列缺失值的百分比
missing_percentages = df.isnull().mean()
print("每列缺失值的百分比:")
print(missing_percentages)

# 获取缺失值大于0.4的列索引
columns_to_drop = missing_percentages[missing_percentages > 0.4].index
#删除这些列
df_dropped_columns = df.drop(columns=columns_to_drop)
print(df_dropped_columns)

   1.4.2 插补法(均值、中位数、众数)

# 0值填补
df_filled_constant = df.fillna(0)
print("\n用0填充缺失值:")
print(df_filled_constant)

# 均值填补,中位数则是df.median()、众数为
df_filled_mean = df.fillna(df.mean())
print("\n用各列的平均值填充缺失值:")
print(df_filled_mean)

# 空格填补,这类填补主要是因为一些字符型变量,有些分析方法如果值为Nan会报错
df_filled_space = df.fillna('')
print(df_filled_space)

   1.4.3 其他方法(模型拟合)

  缺失值的填补还有很多其他方法,上面都是最简单也是最常用的,特别是均值插补。
  对于数值型的变量,还有很多统计学方法进行缺失值填补,比如KNN填充、回归方法、期望值最大化方法、多重填补、随机森林等等,具体可以参考缺失值的具体处理方法
  这里主要介绍直方图梯度提升回归模型进行填补的代码,其思路核心也跟预测一样,利用已知数据预测未知数据。
但他的优势在于允许直接处理包含NaN值的特征列。如果是随机森林模型,利用A、B列的已知数据预测C列的空值,A、B列不允许有空值,会直接导致报错。

import pandas as pd
from sklearn.experimental import enable_hist_gradient_boosting
from sklearn.ensemble import HistGradientBoostingRegressor

# 创建示例 DataFrame
data = {'A': [1, 2, None, 4],
        'B': [5, None, 7, 8],
        'C': [9, None, 11, 12]}
df = pd.DataFrame(data)

# 拆分数据集为已知和未知数据
known_data = df[df['C'].notnull()]
unknown_data = df[df['C'].isnull()]

# 创建特征矩阵 X 和目标变量 y
X_train = known_data[['A', 'B']]
y_train = known_data['C']

# 训练直方图梯度提升回归模型
model = HistGradientBoostingRegressor()
model.fit(X_train, y_train)

# 使用训练好的模型进行预测并填充缺失值
predicted_values = model.predict(unknown_data[['A', 'B']])
df.loc[df['C'].isnull(), 'C'] = predicted_values

print("C列填充缺失值后的 DataFrame:")
print(df)

2.常用函数

 2.1 内置函数

主要内置函数有68个,这里不进行过多解释,详情请见连接:内置函数大全

abs()           dict()        help()         min()         setattr()
all()           dir()         hex()          next()        slice() 
any()           divmod()      id()           object()      sorted() 
ascii()         enumerate()   input()        oct()         staticmethod() 
bin()           eval()        int()          open()        str() 
bool()          exec()        isinstance()   ord()         sum() 
bytearray()     filter()       issubclass()   pow()         super() 
bytes()         float()        iter()         print()       tuple() 
callable()      format()      len()          property()    type() 
chr()           frozenset()   list()         range()       vars() 
classmethod()   getattr()     locals()       repr()        zip() 
compile()       globals()     map()          reversed()    __import__() 
complex()       hasattr()     max()          round() 
delattr()       hash()        memoryview()   set()

 2.2 随机函数

主要的随机函数有7个,需要提前导入random模块

 ①random.random()

random.random() 方法返回一个随机数,没有参数,生成的随机数在 0 至 1 的范围之内。

import random
random.random()

 ②random.uniform()

random.uniform(a , b) 是在指定范围内生成随机数,其有两个参数,一个是范围上限,一个是范围下限,顺序可交换。

import random
random.uniform(2,6)#(6,2)也不影响

 ③random.randint()

random.randint(a , b) 是随机生成指定范围内的整数,其有两个参数,一个是范围上限,一个是范围下限,顺序不可交换。

import random
random.randint(2,6)#(6,2)会报错

 ④random.choice()

random.choice() 是从序列中获取一个随机元素

import random
random.choice('abcdefg&#%^*f'))#随机一个字符:e
random.choice(['apple','pear','peach', 'orange', 'lemon'] )#随机一个字符:orange

 ⑤random.randrange()

random.randrange(a , b , step) 是在指定范围内,按指定基数递增的集合中获得一个随机数,有三个参数,前两个参数a和b代表范围下限和上限,第三个参数是递增增量step。

import random
random.randrange(1,7,2)#1,3,5,7中随机一个数

 ⑥random.shuffle()

random.shuffle() 函数是将一个序列中的元素打乱,随机排序。shuffle函数会对原有的序列进行改变,不返回任何值。

import random
list = ["Python", "is", "powerful", "simple", "and so on..."]
random.shuffle(list)#list元素被打乱

 ⑦random.sample()

random.sample(sequence, k) 函数是从指定序列中随机获取指定长度的片段,原有序列不会改变,有两个参数,第一个参数代表指定序列,第二个参数是需获取的片段长度。

import random
listRandom = ["Python", "is", "powerful", "simple", "and so on..."]
listSample = random.sample(listRandom, 3)
print("随机sample:", listSample)

还有一种用法,最常用的,若一个数据集比较大,使用pandas读出来后,有时会随机抽样,这个是pandas中带的sample函数,不需要导入random模块:

import pandas as pd
df=pd.read_excel('test.xls')
df=df.sample(20000).reset_index(drop=True)#代表随机df的20000条数据,后面的表示重置索引

3.pandas与numpy的使用

pandas和numpy在数据分析中是用的最多的模块,因此按照平时数据分析的逻辑进行总结。在使用前需要先导入pandas和numpy模块。

import pandas as pd
import numpy as np

 3.1 数据读取写入

  3.1.1 导入外部数据

df=pd.read_csv('name.csv',encoing = 'UTF-8',header=1)
#excel没有encoing字段
df=pd.read_excel('name.xlsx')

  3.1.2 直接写入数据

可以写一个字典,然后转换成df;也可以直接定义数据和列名,新建为df。

#通过写一个字典,转df
df = pd.DataFrame({'Name':['张三','李四','王五','赵六','田七'],
        'Age':[18,22,16,25,20], 
        'Gender':['男','女','男','男','女'],
        'Score':[88,95,70,76,85]})

#直接定义df和列名
data = [['张三', 18, '男', 88],
        ['李四', 22, '女', 95],
        ['王五', 16, '男', 70], 
        ['赵六', 25, '男', 76],
        ['田七', 20, '女', 85]]

columns = ['Name', 'Age', 'Gender', 'Score']
df = pd.DataFrame(data, columns=columns)

 3.2 数据检查

数据检查主要是为了了解数据表的整体情况,获得数据表的关键信息、数据的概况,例如整个数据表的大小、所占空间、数据格式、是否有 空值和重复项等等。

#查看数据纬度(行数和列数)
df.shape

#查看数据信息
df.info()

#统计每个类别数
df['Gender'].value_counts()
df['Gender'].value_counts(normalize=True)#百分比
df['Gender'].value_counts(normalize=True).sort_index()#百分比,按索引排序
df['Gender'].value_counts(bins=np.arrange(1,10,1))

#查看数据格式
df.dtypes

#检查空值
df.isnull()
#检查特定列空值
df['Score'].isnull()
#找到一列中最大最小值的行索引
df.idxmax(axis="columns") 
#查看唯一值
df['Name'].unique()

 3.3 数据清洗

 3.4 数据预处理

 3.5 数据提取与筛选

 3.6 数据统计

 3.7 数据输出

4.嵌套循环控制

5.正则表达式匹配

  正则表达式是对字符串(包括普通字符(例如,a 到 z 之间的字母)和特殊字符(称为“元字符”))操作的一种逻辑公式,在各种场景中都会用到,比如数据分析或者爬虫,主要用于字符串的匹配。使用前要先导入re模块。

import re

 5.1 正则基本语法

  推荐一个我写正则时常用来测试正确性的网站:regex101,可以直接测试你写的正则能否有效,还可以看正则用了多少步进行匹配,可以优化正则,很好用。
正则太多了我懒得写,就不详细写了,具体见:正则详细教程
  基本语法网上很多,我掌握的也不全,这里有两篇语法总结比较好的博客:
正则大全正则大全2
  主要记录一下,平时自己常会用到的正则:

表达式描述
.任意非换行字符串
^锚定字符串开头
$锚定字符串结尾
\S任意非空格字符
\s空格字符[空格,换行,返回]
\d十进制数[0-9]
\D非十进制数
\w单字字符,大小写字母,数字,下划线[A-Z,a-z,0-9,_ ]
\W非单字字符,大小写字母,数字,下划线[A-Z,a-z,0-9,_ ]
\转义字符,抑制字符特殊性
.*贪婪匹配
.*?懒惰匹配

 5.2 正则常用函数

  5.2.1 search 函数

   搜索函数,匹配整个字符串,并返回第一个成功的匹配。如果匹配失败,则返回Nonere.search第一个参数表示规则,即你的正则表达式,第二个参数即为需要匹配的字符串

import re
s = "I am a dashuaibi"  #以这个字符串为例
ret = re.search("^I.*bi$",s)  #这里^定限,表示以I开头,$表示以bi结尾,中间.*代表任意字符串
print(ret)
>>>  <re.Match object; span=(0, 16), match='I am a dashuaibi'>
ret = re.search('d.*bi',s)
print(ret)
a = ret.group() #group函数取出匹配到的内容,即a=dashuaibi

>>>  <re.Match object; span=(7, 16), match='dashuaibi'> 
>输出结果match即为匹配到的内容
>输出结果span则为索引,比如第一个例子即为整个字符串,第二个例子的正则式为d和bi及中间的所有部分,因此索引为7-16

  5.2.2 match函数

s = "I am a dashuaibi"
ret = re.match('I.*sh',s)
ret.group()
>>>  'I am a dash'

  5.2.3 escape 函数

   

  5.2.4 complie 函数

   没什么好说的,编译

  5.2.5 结合map的用法

 5.3 正则使用实例

6.面向对象编程

我感觉我都懂,也很简单也不会忘记,但我懒得写,要是后面学的深了我再考虑

7.常见描述统计以及绘图

7.1 描述性统计

7.2 基础绘图(条形图、柱状、饼图)

7.3 相关热力图

7.4 箱线图与小提琴图

7.5 多图组合(子图)

7.6 三维图

8.SciPy库以及常用统计检验

9.简单机器学习

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

九七不会用python

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值