python数据分析/建模代码大全(基础入门款)

闲来无事,整理一下数据分析/处理的代码,python使用这一块最多的两个简单的库,就是numpy和pandas库。 当初作为数模新人,还没有AI,自己摸索整理了一堆代码命令,但是没总结乱七八糟,所以今天总结一下, 做成一个对比表格,可以更加直观他们两个在同一个功能上的代码怎么敲,也算是对我那段三年建模经历的总结。(致失去的青春,致迷茫的数模人,致自由,Passion! )

下面是表格的内容总结,比较基础,后续我更新一下:相关性分析与特征处理(特征选择( 过滤式、包裹式和嵌入式),特征变换),有监督学习(分类,回归),无监督学习(聚类),启发式算法(模拟退火,遗传算法,粒子群,差分进化,鲸鱼算法),主成分分析。 还有一些结果指标和数据可视化(sns和matplotlib)。 算是走完数据分析建模画图全程吧。

!!!注意,本人是个懒人,想要看上面哪个内容,评论区催一下哈哈。对了,下面表格代码看不懂的,附上个国内AI网站,给你登录就可以用,不会就问。通义tongyi.ai_你的全能AI助手-通义千问

1. 数据导入和导出

  • CSV数据导入和导出
  • Excel数据导入和导出
  • HDF5文件的读写

2. 数据操作

  • 表的链接和合并
  • 数据筛选
  • 字符串处理
  • 类型转换

3. 数据结构操作

  • 创建和访问数据框
  • 行列的插入和删除
  • 索引整理

4. 数据处理技巧

  • 数据去重
  • 处理异常值
  • 数据归一化
  • 处理缺失值
  • 数据编码和分箱

5. 高级数据操作

  • 数组排序
  • 分组统计
  • 时间序列处理
  • 多级索引

6. 特殊操作

  • 批量替换
  • 数据透视表
  • 日期差计算
  • 数据变换函数
  • 数据的链接和分割
作用代码
csv数据导入#注明有些csv使用gbk编码的,平时的读取是默认utf8编码,所以需要转换
df1 = pd.read_csv("d2.csv", encoding='cp936')
df1 = pd.read_csv("d2.csv", encoding='cp936', index_col=0)
csv数据导出df.to_csv('G:/第13周Python上课资料/d1.csv', encoding = 'GBK')
df1 = pd.read_csv("d2.csv", encoding='cp936', index_col=0)
 
excel数据导入df2 = pd.read_excel("mobile.xlsx",index_col=0, sheet_name='二季度')
excel数据导出df2.to_excel("a1.xlsx", sheet_name='二季度')

3.两个一起
with pd.ExcelWriter(r'D:\桌面\今天任务\2020C题再开启\修改项目\附件4.xlsx',engine='openpyxl') as w:
data_2_1.to_excel(w,sheet_name='附件1',index=False)
data_2_2.to_excel(w,sheet_name='附件2')

result.to_excel(r"D:\桌面\要交的作业\公司的.xlsx",index=False,header=False)
 
读/写HDF5文件#写,若store.h5文件不存在,则先创建;若已存在,则打开此文件
store = pd.HDFStore('store.h5')
store['dfa'] = df1 # 将df1保存到文件中,键名dfa
store['dfb'] = df2 # 将df2保存到文件中,键名dfb
store.close() # 关闭文件
读/写HDF5文件# 读出已保存的数据可以使用下面的命令。
store = pd.HDFStore('store.h5') # 打开文件
df3 = store['dfa'] # 根据dfa键名取出数据
df4 = store['dfb'] # 根据dfb键名取出数据
表的链接# 8.5.5 数据框连接
'''
Pandas提供了merge()方法用于连接不同数据框的行,类似于数据库的两个表连接查询:
select sno, name from tb1, tb2 where tb1.sno = tb2.sno
'''

df1 = pd.DataFrame({'color':['r', 'b', 'w', 'w'], 'c1':range(4)})

df2 = pd.DataFrame({'color':['b', 'w', 'b'], 'c2':range(2, 5)})


'''
df1和df2有同名列color,pd.merge()自动将同名列作为连接键,
横向连接两个数据框的color值相等的行。连接时丢弃原数据框的索引。
'''

df4 = pd.merge(df1, df2, on='color')

df3 = pd.merge(df1, df2)


'''
两个数据框列名不同时,用 left_on 和 right_on 参数分别指定。
下例指定c1, c2列为键,表示当df1表的c1列值等于df2表的c2列值时满足连接条件。
pd.merge(df1, df2, left_on='c1', right_on='c2')
'''

pd.merge(df1, df2, left_on='c1', right_on='c2')

'''
pd.merge默认做inner内连接,还可指定left /right/outer 等连接方式,
这些连接方式与数据库中的连接规则是类似的。
'''

df2 = pd.DataFrame({'color':['b', 'w', 'g'], 'c2':range(2, 5)})
pd.merge(df1, df2, how='left') # 包含左表所有的行
pd.merge(df1, df2, how='right') # 包含右表所有的行
pd.merge(df1, df2, how='outer') # 包含两表所有的行

'''
与连接有关的另一个方法是pd.concat(),它合并两个数据框。
'''
np.random.seed(7)
df1 = pd.DataFrame(np.random.rand(4).reshape(2, 2), columns=['c1', 'c2'])
df2 = pd.DataFrame(np.random.rand(4).reshape(2, 2), columns=['c1', 'c2'])
pd.concat([df1, df2], ignore_index=True) # 默认沿纵向合并,行数增加
pd.concat([df1, df2], axis=1) # axis=1沿横向合并,列数增加


#合并多个DataFrame
dfs_list = list(dic.values())

# 创建一个空的 DataFrame
merged_df = dfs_list[0]

# 循环逐步合并多个 DataFrame
for i, df in enumerate(dfs_list[1:], start=1):
merged_df = pd.merge(merged_df, df, on=['代码', '年份'], how='left', suffixes=('', f'_{i}'))

 
数据初步处理numpy代码Pandas
范围内随机整数# 读出已保存的数据可以使用下面的命令。
store = pd.HDFStore('store.h5') # 打开文件
df3 = store['dfa'] # 根据dfa键名取出数据
df4 = store['dfb'] # 根据dfb键名取出数据
范围内随机小数(保留小数)##100个1-10的随机数 保留两位小数
random_numbers_1=["{:.2f}".format(random.uniform(1,10)) for i in range(100)]
random_numbers_2= [round(random.uniform(-5, -3), 2) for _ in range(100)]
random_numbers_3=[[round(random.uniform(-5,-3),2)for i in range(10)] for j in range(10)]
范围内不重复的随机整数和小数card=np.arange(1, 55,0.1) # 一副牌
np.random.shuffle(card) #洗牌
筛选数据>>> a[np.where(a > 5)] # 等价于 a[a>5]
x=np.array((70, 75, 92, 68, 89)) # 评分1
y=np.array((75, 69, 93, 70, 85)) # 评分2
np.where(x>y, x, y) # 取x/y两两比较的较大值
np.where(x>y, 1, 0) # x>y则取1, 否则取0

#第二行的第三列
data[1,2]

#获取第三列
data[:,np.newaxis,2]
 
* 布尔 方框选择

1. da_group_drop = da_group_drop[da_group_drop['date']>='2014-11-28']

2. num_a = data[(data.behavior_type != 2) &
(data.behavior_type != 3)]['item_id'].nunique()

3. SJ = SC[SC['user_id'].isin(JG['user_id']
.values.tolist())] #收藏并且加购的表格

4.JJ = JG[~JG['user_id'].isin(SC['user_id']
.values.tolist())] #仅加购的表格

* np.where 得到索引值
字符串处理# 8.5.8 字符串处理
'''
Pandas为字符串提供了形如 “obj.str.方法()” 的一系列命令支持,
这些方法一般在数据清洗、转换时使用。
'''
ser1 = pd.Series(['Beauty and the Beast',
'Captain America: Civil War', 'Jurassic World', 'Toy Story'])

help(ser1.str)

ns1 = ser1.str.len() # 返回字符串长度

ns2 = ser1.str.split() # 分割字符串

ns3 = ser1.str[:6] # 字符串切片

ns4 = ser1.str.contains('War') # 测试电影名中是否包含War

ns5 = ser1.str.lower().str.contains('war') # 转小写再测是否含war

ns6 = ser1.str.replace(' ', '-') # 字符替换,用横线- 替换空格
类型转换##变成list类型
* attr = pv_daily.date.astype('str').to_list()
 

数据一点基础命令介绍Pandas
创建数据框'''
DataFrame(数据框)是Pandas最重要的数据结构。
数据框可视为由行和列构成的二维表格,每行或每列都可视为一个Series。
DataFrame既有行索引(index)又有列索引(columns)
'''
 
data = {'apple': [1100,1050,1200], 'huawei': [1250,1300,1328],
'oppo': [800,850,750]}
df1 = pd.DataFrame(data, index=['一月', '二月', '三月'])

df2 = pd.DataFrame({'apple': {'一月':1100, '二月':1050, '三月':1200},\
'huawei': {'一月':1250, '二月':1300, '三月':1328},\
'oppo' : {'一月':800, '二月':850, '三月':750}})

df1 = pd.DataFrame.from_dict(HanLP.keyphrase_extraction(doc.paragraphs[i].text), orient='index', columns=['Score'])
df1 = df1.sort_values(by='Score', ascending=False).reset_index()
df1.columns = ['关键词', '权重']
df_1 = pd.concat([df_1, df1],ignore_index=False)
'''
数据框可视为二维表格,有index(行)和columns(列)两个重要属性。
在创建数据框时,可以指定index和columns。
'''

frame = pd.DataFrame(np.arange(12).reshape(3, 4),
index=['a','b','c'], columns=['c1', 'c2','c3','c4'])
 
数据筛选
访问/修改数据数据行列 只要有一个是文字,索引就用iloc,不用loc

'''
Pandas提供了三种基本数据结构
Series:带标签的一维数组
DataFrame:带标签的二维数组(即表格)
Panel:带标签的三维数组(若干表格的叠加面板)
主要使用Series和DataFrame。
'''
data = {'apple': [1100,1050,1200,1300], 'huawei': [1250,1300,1328,1450,], 'oppo': [800,850,750,720]}
df = pd.DataFrame(data, index=['一月', '二月', '三月', '四月'])

a1 = df['apple']
a2 = df.apple
b = df[['apple', 'huawei']]

df['apple'] = 100,200,300
df['apple'] = [101,201,301]
df['apple'] = (102,202,303)

print(date1_2_duplicate_drop.loc[:,'发票号码'])#用索引名
print(date1_2_duplicate_drop.iloc[:,0])#用数字


a3 = df['一月'] # 错误,访问一行不能用 df['一月']

a4 = df.loc['一月']

df.loc['一月'] = 1212,1563,802

a5 = df.iloc[0]

a6 = df.loc['一月':'二月']

a7 = df.iloc[0:2]

a8 = df[df.apple>1200]

a9 = df[(df.apple>1200) & (df.huawei>1300)]

df.iat[1,2]

df.at['一月','huawei']

df.query('huawei > 1300')


#series对象具有values和index属性
s1 = pd.Series([10,20,30], index=['a','b','c'])

v1 = s1.values

index1 = s1.index

# 5) 获得/修改series对象中的标签
s1 = pd.Series([10,20,30], index=['a','b','c'])

a1 = s1.index[1] # 获得标签

s1.index[1] = 'x' # 将报错,标签不能单个修改

s1.index = ['a1', 'b1','c1'] # 但允许对标签一次性全部赋值修改

s1.index = ['a1', 'a1', 'c1']

s1.index.value_counts() # 统计每个索引出现的次数
 
行、列的插入和删除行的插入df = pd.DataFrame({'姓名':['a','b'], '学号':['A1','A2'], '成绩1':[98,90], '成绩2':[87,80]})

rdf = df.append({'姓名':'d','学号':'A4','成绩1':89,'成绩2':78}, ignore_index = True) # 行的插入,返回一个新数据框

df = df.append({'姓名':'d','学号':'A4','成绩1':89,'成绩2':78}, ignore_index = True) # 行的插入,在原数据框中新增
 
行、列的插入和删除行的删除rdf = df.drop(2) # 返回删除第2行后的新数据框,原数据框不变

df = df.drop(2)

df.drop(1, inplace=True) # 直接再原数据框中删除第2行后
行、列的插入和删除列的插入df = pd.DataFrame({'姓名':['a','b'], '学号':['A1','A2'], '成绩1':[98,90], '成绩2':[87,80]}, index = [0, 1])

df['性别'] = ['M', 'F'] # 新列赋值方式

df.insert(4, '平均成绩', (df.成绩1 + df.成绩2)/2)
行、列的插入和删除列的删除df.drop('平均成绩', axis = 1, inplace=True)

rdf = df.pop('成绩1')

del df['成绩2']
索引整理# 8.5.2 索引整理
'''
a)通过reindex()方法重建索引,
实现行列的取舍,
重建时保留指定标签的数据,抛弃未指定的标签。
'''
df = pd.read_excel("mobile.xlsx", index_col=0, sheet_name= '二季度')

df2 = df.reindex(['一月', '二月'])

df3 = df.loc[['一月', '二月']]

df4 = df.loc[['一月', '二月', '四月']] # 报错

df5 = df.reindex(['一月', '二月', '四月'])

df6 = df.reindex(['apple', 'huawei','mi'], axis=1)

'''
b) rename()重命名
如果已有的列名或行索引不太合适,可使用rename()方法进行调整。
'''
df = pd.read_excel("mobile.xlsx", index_col = 0, sheet_name= '二季度')

rdf1 = df.rename(columns = {'apple':'Apple', 'huawei':'HW'}) # 更改列名

df.rename(columns = {'apple':'Apple', 'huawei':'HW'}, inplace=True) # 更改列名

df.columns = ['Apple','HW', 'oppo']


rdf2 = df.rename(index = {'一月':'m1', '二月':'m2', '三月':'m3'}) # 更改索引

df.index = ['m1','m2', 'm3']


rdf3 = df.rename({'一月':'m1', '二月':'m2', '三月':'m3'}, axis = 0)


'''
c) set_index()重新设定索引列
如果想用另一列做索引列,可用set_index()方法变更。
'''
df = pd.DataFrame({'姓名':['a','b'], '学号':['A1','A2'], '成绩1':[98,90], '成绩2':[87,80]})

df3 = df.set_index('学号')
# 返回的新数据框将学号列设为索引

df.set_index('学号', inplace=True) # 在原数据框上修改

df3 = df3.reset_index()

df4 = df3.set_index('姓名')
 
数据中级处理代码Pandas
数据去重numpy.unique(ar, return_index=False, return_inverse=False, return_counts=False, axis=None)* uv_daily = data.groupby('date')['user_id']
.apply(lambda s:s.drop_duplicates().count())
.rename('uv').reset_index()

* uv_daily = data.groupby('date')['user_id']
.nunique().rename('uv').reset_index()


'''
数据中含有重复值时,使用下列方法处理。
s.duplicated(), s.drop_duplicates()
'''
#重复值观察
date1_2_duplicate=date1_2.duplicated('发票号码').sum()
date1_3_duplicate=date1_3.duplicated('发票号码').sum()
#删除重复值 会影响索引
date1_2_duplicate_drop=date1_2.drop_duplicates('发票号码')
date1_3_duplicate_drop=date1_3.drop_duplicates('发票号码')

s = pd.Series(list('abacdefanla'))

b = s.duplicated() # 检测重复值,返回布尔数组,重复值处显示True

s1 = s.drop_duplicates() # 删除重复值,返回一个新对象



df = pd.DataFrame({'c1': ['a', 'a', 'b'], 'c2': ['a', 'b', 'b'], 'c3': ['a', 'b', 'x']})

b1 = df.duplicated() # 整行检测, 英标[ˈduːplɪkeɪtɪd]


b2 = df.duplicated('c1') # 整列检测

df2 = df.drop_duplicates('c1') # c1列上删除重复值
 
数据异常值3-Sigma规则
for col in data.select_dtypes(include=[np.number]).columns:
mean = data[col].mean()
std = data[col].std()
upper_limit = mean + 3 * std
lower_limit = mean - 3 * std

# 找出异常值的索引并替换
data.loc[data[col] > upper_limit, col] = data[col].median()
data.loc[data[col] < lower_limit, col] = data[col].median()
箱型图(IQR)方法
for col in data.select_dtypes(include=[np.number]).columns:
Q1 = data[col].quantile(0.25)
Q3 = data[col].quantile(0.75)
IQR = Q3 - Q1
lower_limit = Q1 - 1.5 * IQR
upper_limit = Q3 + 1.5 * IQR

# 找出异常值的索引并替换
data.loc[data[col] > upper_limit, col] = data[col].median()
data.loc[data[col] < lower_limit, col] = data[col].median()
#使用value counts()函数查石df1中"省份”的分布情况以以及查石表格台份这print(df1.['省份].value counts0)
#使用replace0函数进行替换df1数据中拼写错误的值,并值给原数据

df1[省份]= df1[省份].replace(浙省,浙江省)

#使用print0函数输出进行替换之后的df1中"省份”的数据
print(df1[省份])

#使用value counts0函数查看df1中"省份”的分布情况以及检查是否修改成功,并使用print0函数进行 输出

print(df1[’省份’].value_counts())
 
数据无量纲化(归一化)from sklearn.preprocessing import MinMaxScaler
data = [[-1, 2], [-0.5, 6], [0, 10], [1, 18]]
import pandas as pd
pd.DataFrame(data)
#实现归一化
scaler = MinMaxScaler() #实例化
scaler = scaler.fit(data) #fit,在这里本质是生成min(x)和max(x)
result = scaler.transform(data)
result_ = scaler.fit_transform(data)
scaler.inverse_transform(result) #将归一化后的结果逆转

#当X中的特征数量非常多的时候,fit会报错并表示,数据量太大了我计算不了
#此时使用partial_fit作为训练接口
#scaler = scaler.partial_fit(data)

###别的
import numpy as np
X = np.array([[-1, 2], [-0.5, 6], [0, 10], [1, 18]])
#归一化
X_nor = (X - X.min(axis=0)) / (X.max(axis=0) - X.min(axis=0))
X_nor
#逆转归一化
X_returned = X_nor * (X.max(axis=0) - X.min(axis=0)) + X.min(axis=0)
X_returned

#### 数据无量纲化:数据标准化

当数据(x)按均值(μ)中心化后,再按标准差(σ)缩放,数据就会服从为均值为0,方差为1的正态分布(即标准正态分 布)

from sklearn.preprocessing import StandardScaler
data = [[-1, 2], [-0.5, 6], [0, 10], [1, 18]]
scaler = StandardScaler() #实例化
scaler.fit(data) #fit,本质是生成均值和方差
x_std = scaler.transform(data) #通过接口导出结果
result=scaler.fit_transform(data)
 
数据缺失值处理
 
import pandas as pd
data = pd.read_csv(r"C:\work\learnbetter\micro-class\week 3
Preprocessing\Narrativedata.csv",index_col=0)
data.head()

data.loc[:,"Age"] = data.loc[:,"Age"].fillna(data.loc[:,"Age"].median())
#.fillna 在DataFrame里面直接进行填补
data.dropna(axis=0,inplace=True)
#.dropna(axis=0)删除所有有缺失值的行,.dropna(axis=1)删除所有有缺失值的列
#参数inplace,为True表示在原数据集上进行修改,为False表示生成一个复制对象,不修改原数据,默认False




# 1) nan缺失值处理(决策树填充)
a = np.array([1, 5, np.nan, np.nan, 10])
a.sum()
a.mean()

s = pd.Series(a)#变成series后可忽略nan进行处理
s.sum()
s.mean()

b1 = s.isnull()
b2 = s.notnull()


b1 = s.isnull().sum()#计算缺失值个数


df = pd.DataFrame(np.arange(12).reshape(4, 3), index=list('abcd'),columns= list('xyz'))
df.iloc[1:3, 0:2] = np.nan
df.iloc[2, 2] = np.nan

a1 = df.dropna()

a2 = df.dropna(axis = 1)

a3 = df.dropna(how='all') # 表示某行的所有数据都为nan才删除

a4 = df.dropna(thresh = 2) # 保留非nan值个数>=2的数据行/列

a41 = df.dropna(thresh = 1) # 保留非nan值个数>=1的数据行/列

df.fillna(0)#填充是按列来填充的

df.fillna(method = 'ffill')#用前一个值填充

df.fillna(method = 'bfill')#用下一个值填充

df.fillna(value = df.mean())#用平均值填充

#######一些例子
hh=data_touzi_all#放表名

all_1=hh.groupby(['基金代码_FdCd']).mean().reset_index()
all_1

#空白值观察
print('数据表 初始数据信息')
print(all_1.info())
print("初步空白值:\n{}".format(all_1.isnull().sum()))

#缺失值处理

# 计算每列的缺失值比例
aa=all_1#存放数据
missing_percentages = aa.isnull().mean()

# 找到缺失值比例大于60%的列
missing_above_60 = missing_percentages[missing_percentages > 0.6]

# 删除缺失值比例大于60%的列
df = aa.drop(missing_above_60.index, axis=1)

df=df.iloc[:,[0,6,8,9,10]]
#删除空白值模块 按最高向下去掉空白值

missing_percentage = df.isnull().sum() / len(df) * 100

# 按照缺失值比例升序排序
missing_percentage_sorted = missing_percentage.sort_values(ascending=True)
print(missing_percentage_sorted)
# 删除缺失值最高的列,直到所有行都没有缺失值或者无法再删除
while True:
# 找到第一个缺失值比例最高的列
col_to_drop = missing_percentage_sorted.index[-1]
print(col_to_drop)
# 如果该列存在缺失值,删除该行
if df[col_to_drop].isnull().sum() > 0:
df.dropna(subset=[col_to_drop], inplace=True)
# 重新计算每列缺失值比例
missing_percentage = df.isnull().sum() / len(df) * 100
# 按照缺失值比例升序排序
missing_percentage_sorted = missing_percentage.sort_values(ascending=True)
# 如果所有行都没有缺失值或者无法再删除,则退出循环
if missing_percentage_sorted.iloc[-1] == 0 or len(missing_percentage_sorted) == 0:
break
print('删除空白值后')
df.isnull().sum()

x0_all=df


 
数据编码
(数据分箱)
为了让数据适 应算法和库,我们必须将数据进行编码,即是说,将文字型数据转换为数值型

preprocessing.LabelEncoder:标签专用,能够将分类转换为分类数值

from sklearn.preprocessing import LabelEncoder
data.iloc[:,-1] = LabelEncoder().fit_transform(data.iloc[:,-1])
preprocessing.OrdinalEncoder:特征专用,能够将分类特征转换为分类数值


from sklearn.preprocessing import OrdinalEncoder
data_.iloc[:,1:-1] = OrdinalEncoder().fit_transform(data_.iloc[:,1:-1])

 
# 8.5.6 数据分段
'''
数据分段是将数据按指定的区间归类,以统计每个区间的数据个数。
例如将成绩分为优、良、中、不及格区间段。
数据分段的方法是pd.cut(),分段前要自定义数据区间段,并设置对应的标识文字。
'''

np.random.seed(7)
score = np.random.randint(30, 100, size=100) # 生成100个随机整数

bins = [0, 59, 70, 85, 100] # 定义区间段
labels = ['不及格', '中', '良', '优'] # 设置各段的标识文字
scut = pd.cut(score, bins, labels=labels) # 将score按bins分段
s = pd.value_counts(scut) # 统计各类别的数据个数
 
多维数组转一维数组.ravel()
数组排序b=np.random.randint(1, 20, size=10)
c=b.copy() # 备份

b=np.sort(b)#从小到大排序
#数组排序不支持列表的reverse=True参数,要从大到小排如下所示:
b_reverse=b[np.argsort(-b)] # 注意 -b

#多维数组排序时可指定 axis=0(行) / 1(列),排序时默认按最大轴排序

np.random.seed(7)
b=np.random.randint(1, 50, size=15).reshape(3, 5)
np.sort(b) #默认按axis=1 ,在水平方向上排序
np.sort(b, axis=0) # 在竖直方向上排序
# 8.5.4 排序和排名
# a)排序
* top10_Good = item_type_df
.sort_values(by=4, ascending=False)[:10]

s = pd.Series([2, 5, 1], index=['d', 'a', 'b'])

ser1 = s.sort_index() # 按索引'a b d'排序,返回新对象,并不改变原对象

ser2 = s.sort_values() # 按数据值1 2 5排序

ser3 = s.sort_index(ascending=False) # 按索引逆序排


np.random.seed(7)
arr = np.array(np.random.randint(1, 100, size=9)).reshape(3, 3)
df = pd.DataFrame(arr.reshape(3, 3), columns=['x','z','y'], index=['a','c','b'])

df.sort_index()

df.sort_index(axis=1)

df.sort_index(axis=1, ascending = False) # 按列名索引降序z y x排列


df.sort_values(by='y') # 按y列的数值排序

df.sort_values(by=['y', 'z']) # 先参照y列,再z列排序

df.sort_values(by='b', axis = 1) # 按b列的数值排序

# b) 排名
s = pd.Series([3, 5, 8, 5], index=list('abcd'))

l = s.rank() # 排名,默认按数据值升序排名

l = s.rank(ascending=False) # 降序

l = s.rank(method='first') # 指定名次号的生成方法为first
 
分组统计#-----> 8.6 分组统计

# 8.6.1 分组对象概述
'''
Pandas支持数据分组,功能类似数据库中的group by(分组统计)
'''

df = pd.DataFrame({'color': ['red', 'white', 'black', 'red', 'black', 'red'], 'size':['s','m','b','s','m','b'], 'price': [10, 11, 12, 20, 21, 22], 'quantity': [1, 2, 3, 3, 4, 5]})

g = df.groupby('color') # 按color分组


for x in g:
print(x)

for name, group in g:
print(name) # 输出组名
print(group) # 组内容

# 8.6.2 分组对象的统计方法
a1 = g.size() # 列出每个分组的数据条数
a2 = g.sum() # sum只对数值列求和,非数值列未显示
a3 = g.get_group('black') # 指定返回black组数据
a4 = g.head(2) # 取每个分组的头2个数据
a5 = g.nth(0) # 取每组的第0个数据
a6 = g.price.describe() # 对price列做describe,得到一组常用统计量


'''
分组对象有一个aggregate合计方法(简写为agg),它允许传递多个统计函数,
因此可以一次性得到多个统计值。
'''

g.quantity.agg((np.sum, np.mean, np.max, np.min))
g.quantity.agg([('均值','mean'), ('最大值','max')]) # 定义列名

#自定义函数聚合
df = pd.DataFrame({'color': ['red', 'white', 'black', 'red',
'black', 'red'], 'size':['s','m','b','s','m','b'],
'price': [10, 11, 12, 20, 21, 22], 'quantity':
[1, 2, 3, 3, 4, 5]})

g = df.groupby('color') # 按color分组

def squre_sum (x):
s = 0
for i in x.values:
s = s + i**2
return s

g.quantity.agg(squre_sum)

##例子
groupby([列名1,列名2])['列名'].count()#聚合函数count()

groupby('列名A').sum()#聚合函数sum()

data.groupby('州')['州'].count().rename('哈哈').reset_index()
**
***重置索引
p1=p1.reset_index(drop=True)


 
时间序列#-----> 8.7 时间序列
'''
Pandas最初研发的目的是作为金融数据分析包,因此提供了丰富的时间序列处理方法。
时间序列做索引,运算时会自动按日期对齐。
'''

# 8.7.1 Pandas中的时间函数
'''
拿到timestamp的年月日:

date1['年的日期']=date1['开票日期'].dt.year
date2['年的日期']=date2['开票日期'].dt.year

date1['月期']=date1['开票日期'].dt.month
date2['月期']=date2['开票日期'].dt.month
a) to_datetime(): 将字符串转换为时间,识别不同格式的日期字符串。
'''

pd.to_datetime('2022-11-28')

pd.to_datetime(['28/11/2022', '2022.11.28'])

pd.to_datetime('2022-11-28 15:30:00')

today = pd.datetime.now()

t2 = today + pd.DateOffset(days=3)


'''
b) date_range():用于产生指定日期段内的一系列日期时间值。
pd.date_range(起始日期, 结束日期, periods=周期数, freq=日期频率)
'''

dt1 = pd.date_range('2019-02-01', '2019-02-28')
# 默认频率1天
dt2 = pd.date_range('2019-02-01', '2019-02-28', freq='3D'
) # 频率为每3天
dt3 = pd.date_range('2019-01-01', periods=6, freq='3D')
# 每3天1个日期


'''
有时需要对日期序列做shift(移动)转换,以计算相邻日期间的数据变动。
'''

np.random.seed(7)
dates = pd.date_range('2018-9-1', periods=4) # 生成4个日期索引值
s = pd.Series(np.random.rand(4), index=dates)

s1 = s.shift(1) # 后移一个数据位

diff = s - s.shift(1)

# ((s - s.shift(1)) / s.shift(1)).map(lambda x: format(x, '.2%'))
# 变动百分比并格式化


# 8.7.2 时间频率变换
'''
用时间作为索引时,可以方便地按时间段查看数据。
对时间序列数据可用resample()方法按不同频率进行重采样,然后对样本进行计算。
'''
np.random.seed(7)
dates = pd.date_range('2018-1-1', periods=365)
s = pd.Series(np.random.randn(365), index=dates) # 2018年模拟数据

data1 = s['2018-1'] # 选取2018年1月的数据
data2 = s['2018-02' : '2018-04'] # 选取2018年2月至4月的数据
data3 = s.resample("1M").mean() # 按月求均值
data4 = s.resample("10D").sum() # 每10天求和

data5 = s.resample("10D").agg([np.max, np.min]) # 每10天一次采样,返回每组样本的最大值、最小值
 
多级索引# 8.5.7 多级索引

'''
Pandas支持一级索引,也支持多级索引(MultiIndex)。
多级索引可以更好地表达数据之间的联系。
'''
data = np.arange(2, 10).reshape(4, 2)
df1 = pd.DataFrame(data, index=[list('AABB'), list('rgrg')], columns=['一月','二月'])

mindex = pd.Index([('A', 'r'), ('A', 'g'), ('B', 'r'), ('B', 'g')], names=["Product", "Color"])
df2 = pd.DataFrame(data, index = mindex, columns=['一月','二月'])

df1.loc['B'] # 查看B类产品

df2.loc[('B', 'r')] # 查看B类中的红色r产品

df2.loc[(slice(None), 'r'), :] # 查看所有的红色r产品

df2.loc['A'].sum() # A 类每个月数量和

df2.loc['A'].sum().sum() # 所有A类数量和

df2.loc[(slice(None), 'r'), :].sum().sum() # r类数量和

df2.groupby(level='Product').sum()

df2.groupby(level='Product').sum().sum(axis=1)


df2=df1.unstack() # 默认将内层的1级行索引转为列索引

df3=df1.stack() # 变为三级(0,1,2)索引了

df3.groupby(level=2).sum()
一些特殊的操作代码
批量替换def live_year(x):
if x < 365:
return '不到1年'
if x < 365 * 2:
return '1-2年'
if x < 365 * 3:
return '2-3年'
if x < 365 * 4:
return '3-4年'
if x < 365 * 5:
return '4-5年'
if x < 365 * 10:
return '5-10年'
return '10年以上'

s = data.groupby(data['live_days'].apply(lambda x: live_year(x))).size()
# 增加 Country/Region 和 Province/State 的中文冗余列 Country/Region_zh 、Province/State_zh
country_map = {
'Singapore Rep.': '新加坡', 'Dominican Rep.': '多米尼加', 'Palestine': '巴勒斯坦', 'Bahamas': '巴哈马', 'Timor-Leste': '东帝汶',
'Afghanistan': '阿富汗', 'Guinea-Bissau': '几内亚比绍', "Côte d'Ivoire": '科特迪瓦', 'Siachen Glacier': '锡亚琴冰川',
"Br. Indian Ocean Ter.": '英属印度洋领土', 'Angola': '安哥拉', 'Albania': '阿尔巴尼亚', 'United Arab Emirates': '阿联酋',
'Argentina': '阿根廷', 'Armenia': '亚美尼亚', 'French Southern and Antarctic Lands': '法属南半球和南极领地', 'Australia': '澳大利亚',
'Austria': '奥地利', 'Azerbaijan': '阿塞拜疆', 'Burundi': '布隆迪', 'Belgium': '比利时', 'Benin': '贝宁', 'Burkina Faso': '布基纳法索',
'Bangladesh': '孟加拉国', 'Bulgaria': '保加利亚', 'The Bahamas': '巴哈马', 'Bosnia and Herz.': '波斯尼亚和黑塞哥维那', 'Belarus': '白俄罗斯',
'Belize': '伯利兹', 'Bermuda': '百慕大', 'Bolivia': '玻利维亚', 'Brazil': '巴西', 'Brunei': '文莱', 'Bhutan': '不丹',
'Botswana': '博茨瓦纳', 'Central African Rep.': '中非', 'Canada': '加拿大', 'Switzerland': '瑞士', 'Chile': '智利',
'China': '中国', 'Ivory Coast': '象牙海岸', 'Cameroon': '喀麦隆', 'Dem. Rep. Congo': '刚果民主共和国', 'Congo': '刚果',
'Colombia': '哥伦比亚', 'Costa Rica': '哥斯达黎加', 'Cuba': '古巴', 'N. Cyprus': '北塞浦路斯', 'Cyprus': '塞浦路斯', 'Czech Rep.': '捷克',
'Germany': '德国', 'Djibouti': '吉布提', 'Denmark': '丹麦', 'Algeria': '阿尔及利亚', 'Ecuador': '厄瓜多尔', 'Egypt': '埃及',
'Eritrea': '厄立特里亚', 'Spain': '西班牙', 'Estonia': '爱沙尼亚', 'Ethiopia': '埃塞俄比亚', 'Finland': '芬兰', 'Fiji': '斐',
'Falkland Islands': '福克兰群岛', 'France': '法国', 'Gabon': '加蓬', 'United Kingdom': '英国', 'Georgia': '格鲁吉亚',
'Ghana': '加纳', 'Guinea': '几内亚', 'Gambia': '冈比亚', 'Guinea Bissau': '几内亚比绍', 'Eq. Guinea': '赤道几内亚', 'Greece': '希腊',
'Greenland': '格陵兰', 'Guatemala': '危地马拉', 'French Guiana': '法属圭亚那', 'Guyana': '圭亚那', 'Honduras': '洪都拉斯',
'Croatia': '克罗地亚', 'Haiti': '海地', 'Hungary': '匈牙利', 'Indonesia': '印度尼西亚', 'India': '印度', 'Ireland': '爱尔兰',
'Iran': '伊朗', 'Iraq': '伊拉克', 'Iceland': '冰岛', 'Israel': '以色列', 'Italy': '意大利', 'Jamaica': '牙买加', 'Jordan': '约旦',
'Japan': '日本', 'Kazakhstan': '哈萨克斯坦', 'Kenya': '肯尼亚', 'Kyrgyzstan': '吉尔吉斯斯坦', 'Cambodia': '柬埔寨', 'Korea': '韩国',
'Kosovo': '科索沃', 'Kuwait': '科威特', 'Lao PDR': '老挝', 'Lebanon': '黎巴嫩', 'Liberia': '利比里亚', 'Libya': '利比亚',
'Sri Lanka': '斯里兰卡', 'Lesotho': '莱索托', 'Lithuania': '立陶宛', 'Luxembourg': '卢森堡', 'Latvia': '拉脱维亚', 'Morocco': '摩洛哥',
'Moldova': '摩尔多瓦', 'Madagascar': '马达加斯加', 'Mexico': '墨西哥', 'Macedonia': '马其顿', 'Mali': '马里', 'Myanmar': '缅甸',
'Montenegro': '黑山', 'Mongolia': '蒙古', 'Mozambique': '莫桑比克', 'Mauritania': '毛里塔尼亚', 'Malawi': '马拉维',
'Malaysia': '马来西亚', 'Namibia': '纳米比亚', 'New Caledonia': '新喀里多尼亚', 'Niger': '尼日尔', 'Nigeria': '尼日利亚',
'Nicaragua': '尼加拉瓜', 'Netherlands': '荷兰', 'Norway': '挪威', 'Nepal': '尼泊尔', 'New Zealand': '新西兰', 'Oman': '阿曼',
'Pakistan': '巴基斯坦', 'Panama': '巴拿马', 'Peru': '秘鲁', 'Philippines': '菲律宾', 'Papua New Guinea': '巴布亚新几内亚',
'Poland': '波兰', 'Puerto Rico': '波多黎各', 'Dem. Rep. Korea': '朝鲜', 'Portugal': '葡萄牙', 'Paraguay': '巴拉圭',
'Qatar': '卡塔尔', 'Romania': '罗马尼亚', 'Russia': '俄罗斯', 'Rwanda': '卢旺达', 'W. Sahara': '西撒哈拉', 'Saudi Arabia': '沙特阿拉伯',
'Sudan': '苏丹', 'S. Sudan': '南苏丹', 'Senegal': '塞内加尔', 'Solomon Is.': '所罗门群岛', 'Sierra Leone': '塞拉利昂',
'El Salvador': '萨尔瓦多', 'Somaliland': '索马里兰', 'Somalia': '索马里', 'Serbia': '塞尔维亚', 'Suriname': '苏里南',
'Slovakia': '斯洛伐克', 'Slovenia': '斯洛文尼亚', 'Sweden': '瑞典', 'Swaziland': '斯威士兰', 'Syria': '叙利亚', 'Chad': '乍得',
'Togo': '多哥', 'Thailand': '泰国', 'Tajikistan': '塔吉克斯坦', 'Turkmenistan': '土库曼斯坦', 'East Timor': '东帝汶',
'Trinidad and Tobago': '特里尼达和多巴哥', 'Tunisia': '突尼斯', 'Turkey': '土耳其', 'Tanzania': '坦桑尼亚', 'Uganda': '乌干达',
'Ukraine': '乌克兰', 'Uruguay': '乌拉圭', 'United States': '美国', 'Uzbekistan': '乌兹别克斯坦', 'Venezuela': '委内瑞拉',
'Vietnam': '越南', 'Vanuatu': '瓦努阿图', 'West Bank': '西岸', 'Yemen': '也门', 'South Africa': '南非', 'Zambia': '赞比亚',
'Zimbabwe': '津巴布韦', 'Comoros': '科摩罗'
}

province_map = {
'Anhui': '安徽', 'Beijing': '北京', 'Chongqing': '重庆', 'Fujian': '新疆', 'Gansu': '甘肃', 'Guangdong': '广东',
'Guangxi': '广西', 'Guizhou': '贵州', 'Hainan': '海南', 'Hebei': '河北', 'Heilongjiang': '黑龙江', 'Henan': '河南',
'Hong Kong': '香港', 'Hubei': '湖北', 'Hunan': '湖南', 'Inner Mongolia': '内蒙古', 'Jiangsu': '江苏',
'Jiangxi': '江西', 'Jilin': '吉林', 'Liaoning': '辽宁', 'Macau': '澳门', 'Ningxia': '宁夏', 'Qinghai': '青海',
'Shaanxi': '陕西', 'Shandong': '山东', 'Shanghai': '上海', 'Shanxi': '山西', 'Sichuan': '四川', 'Tianjin': '天津',
'Tibet': '西藏', 'Xinjiang': '新疆', 'Yunnan': '云南', 'Zhejiang': '浙江', 'Fujian':'福建', 'Taiwan': '台湾'
}

confirmed_data['Country/Region_zh'] = confirmed_data['Country/Region'].apply(lambda x: country_map.get(x, x))
deaths_data['Country/Region_zh'] = deaths_data['Country/Region'].apply(lambda x: country_map.get(x, x))
recovered_data['Country/Region_zh'] = recovered_data['Country/Region'].apply(lambda x: country_map.get(x, x))

confirmed_data['Province/State_zh'] = confirmed_data['Province/State'].apply(lambda x: province_map.get(x, x))
deaths_data['Province/State_zh'] = deaths_data['Province/State'].apply(lambda x: province_map.get(x, x))
recovered_data['Province/State_zh'] = recovered_data['Province/State'].apply(lambda x: province_map.get(x, x))
路径拼接path = os.path.join(os.path.join(os.getcwd(),
"文件夹名"), inp_code + ".csv")
 
数据透视表# 8.6.3 数据透视表
'''
Excel中有一个数据透视表功能,Pandas提供了类似的命令pivot_table()。
'''
df = pd.DataFrame({'color': ['red', 'white', 'black', 'red', 'black', 'red'],
'size':['s','m','b','s','m','b'], 'price': [10, 11, 12, 20, 21, 22],
'quantity': [1, 2, 3, 3, 4, 5]})

df.pivot_table(index='color', values='quantity', aggfunc='sum')

df.pivot_table(index='color', columns='size', values='quantity',
aggfunc='sum')

'''
values:需要汇总计算的列,可多选
index:行分组键,一般是用于分组的列名或其他分组键,作为结果DataFrame的行索引
columns:列分组键,一般是用于分组的列名或其他分组键,作为结果DataFrame的列索引
aggfunc:聚合函数或函数列表,默认为平均值
fill_value:设定缺失替换值
margins:是否添加行列的总计
dropna:默认为True,如果列的所有值都是NaN,将不作为计算列,False时,被保留
margins_name:汇总行列的名称,默认为All
observed:是否显示观测值
'''

df = pd.read_excel("高考分数线1420.xlsx")

# 每个地区的平均分数线
result1 = df.pivot_table(index='地区', values='分数线', aggfunc='mean')
result1.sort_values(by = '分数线',ascending = False)

# 每个地区的不同年份所有类别的平均分数线
result2 = df.pivot_table(index='地区', columns='年份', values='分数线', aggfunc='mean')


# 不同地区、不同考生类别、不同年份的分数线
result3 = df.pivot_table(index=['地区', '考生类别'], columns='年份', values='分数线')
 
求日期差* buy_again_days1=buy_again_days.groupby('user_id')
.date.apply(lambda x:x.sort_values().diff(1).dropna())//求日期差
含对每个元素进行变换的函数df = pd.DataFrame(np.arange(9).reshape(3,3), index=list('abc'), columns=list('xyz'))
df.sum() # 默认按axis=0 行求和
df.sum(axis=1)
df.sum().sum()


np.random.seed(7)
ar=np.random.randint(0,11,size=(3,3))
df = pd.DataFrame(ar, index=list('abc'), columns=list('xyz'))

f = lambda x: x.max() - x.min()

t1 = df.apply(f) # 在axis=0(纵向)求 最大值-最小值

t2 = df.apply(f, axis=1)


p = df.applymap(lambda x:str(x)+'︒c') # 在每个数据上变换
t3 = p.applymap(lambda x:int(x[:-2]))
t4 = p.x.map(lambda x: x[:-2]+'度')
 
数据的链接和分割np.hstack((arr1, arr2))
np.vstack((arr2, arr3))

split_arrays = np.hsplit(array2, [2,4,6])#从第二列,4列,6列切开
split_arrays = np.vsplit(array2, [2,4,6])#从第二列,4列,6列切开

说点心里话:AI发展很快,不会你一问就可以得到结果了,但是不能每次都问吧?这就是这个文章存在的意义。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值