文章目录

  • 前言
  • 1、读取数据文件
    • 1.1 读取excel数据文件
    • 1.2 读取csv文件
    • 1.3 读取数据时,跳过尾行
    • 1.4 读取特定分割符的数据文件
    • 1.5 使用c或者python作为读取文件的引擎
    • 1.6 使用迭代器读取超大文件
  • 2、查看数据的基本信息
  • 3、有关空值处理
    • 3.1 行的空值处理
    • 3.2 列的空值处理
    • 3.3 空值的填充
    • 3.4 空值使用所在列或者所在行的均值、中位数来填补
  • 4、dataframe 取(定位)数据的操作
    • 4.1 按给定列名取数,类似字典操作:df['列名']
    • 4.2 按行默认的行索引号选取数据:df.loc
    • 4.3 按给定列名以及行索引取出数据
    • 4.4 df.iloc利用index获取行数据或者列数据
  • 5、通过复杂规则取数
  • 6、调整列位置、列的增、删
  • 7、单元格的字符相关处理
  • 8、有关遍历行的处理
  • 9、DataFrame和DataFrame合并、关联查询等
    • 9.1 DataFrame和DataFrame合并
    • 9.2 DataFrame和DataFrame之间的关联查询
  • 10、groupby基本用法

前言

  以往项目中也有引入Pandas,用于有关数据处理和分析的环节,结合Python的Web开发,很容易开发出一款轻量BI系统。Pandas、Numpy、Scipy、matplotlib、scikit-learn和Jupyter Notebook结合使用,完全可以组成非常出色的数据分析与挖掘的生产环境工具,数据方面的应用,比matlab强不少,以至于本人也不断强化这方面的积累。单独拿出这方面技能,即可完成数据分析师的相关工作(又称提数工程师)。本文主要归档一些高频使用的预处理方面的函数,注意本文不涉及Pandas数据挖掘和数理统计方面的知识点(会在另外blog给出)。

1、读取数据文件

  读取数据的相关接口使用在pandas官网的document有非常详细的说明:在IO tools部分。pandas 不仅能读取基本常用的Excel、csv、文本,还可以读取hadoop文件,或者直接读取数据库等

1.1 读取excel数据文件

  • 加载Excel表,使用skiprows=1跳过首行
    并指定加载的列,注意数据文件的编码,默认utf-8,常用还有gb2312,根据自身数据而定。

    %%timeit
    raw_pd = pd.read_excel(data_file,,skiprows=1,usecols=[1,2,4],name=['item_id','item_name','price'],encoding='gb2312')
    181 ms ± 1.32 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
    

    这里可以为每个执行单元之前加入%%timeit,观察其耗时情况。

  • 加载Excel表,使用header=0跳过有列标题的首行
    除了使用skiprows=1可跳过首行,header=0也可以实现同样效果

    raw_pd = pd.read_excel(data_file,header=0,usecols=[1,2,4],name=['item_id','item_name','price'],encoding='gb2312')
    
  • 加载Excel表,首行为数据,不是列标题
    若该表第一行不是列标题行而是数据行,则需要指定header=None,否则读取后,第一行数据会被作为column name

    raw_pd=pd.read_excel(data_file,usecols=[1,2,4],name=['item_id','item_name','price'],header=None,encoding='utf-8')
    
  • 加载Excel表,读取前n行数据
    若数据文件大小为几个G,显然若直接全量读取,内存会挤爆,因此可以先读取前n看看。使用nrows=500,表示只读取前500行。

    raw_pd=pd.read_excel(data_file,usecols=[1,2,4],name=['item_id','item_name','price'],header=None, nrows=500,encoding='utf-8')
    
  • 加载Excel表,跳过所有空白行
    若有些表出现了不定数量的空白行,可以使用skip_blank_lines=True处理

    raw_pd=pd.read_excel(data_file,usecols=[1,2,4],name=['item_id','item_name','price'],header=None,skip_blank_lines = True, nrows=500,encoding='utf-8')
    
  • 加载Excel表,通过自定规则,跳过满足规则的行
    例如跳过有值为单数的行,定义更复杂的函数,用于跳过满足复杂规则的行。不过,除非这些行很多,否则可以在读取后,直接用正则drop掉来得更有效。

      pd.read_csv(data_file, skiprows=lambda x: x % 2 != 0)
    

1.2 读取csv文件

  读取csv文件跟读取Excel文件区别不大,这里简单给出示例

raw_pd=pd.read_csv(data_file,usecols=[1,2,4],name=['item_id','item_name','price'],header=None,nrows=500,encoding='gb2312')

读取文件,需要注意的地方一般是选择编码,数据文件的编码决定读取数据后,是否正常显示。

1.3 读取数据时,跳过尾行

有些报表一般会在表(例如财务系统导出)的后几行写上制表人、制表日期
这里要注意,若使用c engine,则无法使用从尾部跳过数据的功能:

skipfooter : int, default 0

Number of lines at bottom of file to skip (unsupported with engine=’c’).

raw_pd=pd.read_csv(data_file,usecols=[1,2,4],name=['item_id','item_name','price'],header=None, skipfooter=5,encoding='gb2312')

1.4 读取特定分割符的数据文件

read_csv也可以读取任意文本文件,只需要指定列分割符。

raw_pd=pd.read_csv('data_file.txt',sep='||',encoding='utf-8')

1.5 使用c或者python作为读取文件的引擎

pd.read_*** 方法默认使用python解释器作为读取文件engine,若数据文件大,可选择c engine

engine : {'c', 'python'}

Parser engine to use. The C engine is faster while the Python engine is currently more feature-complete.

1.6 使用迭代器读取超大文件

参考官网文档给出的示例,使用iterator=True, 或者chunksize=4读取超大文件,返回的是TextFileReader,是一个文件迭代器

chunksize方式:

In [187]: reader = pd.read_csv('tmp.sv', sep='|', chunksize=4)In [188]: reader
Out[188]: <pandas.io.parsers.TextFileReader at 0x7f2b428c17f0>In [189]: for chunk in reader:.....:     print(chunk)

iterator=True方式:
使用iterator=True方式,值读取前面5行,放回的也是df对象

In [190]: reader = pd.read_csv('tmp.sv', sep='|', iterator=True)In [191]: chunk_pd=reader.get_chunk(5)
chunk_pd.head()

当然最佳的方式是两者结合使用:返回迭代器方式,并指定分块读取,例如分64k读取

iter_df=pd.read_csv(large_file,iterator=True,chunksize=64*1024)

2、查看数据的基本信息

读入数据后,一般需要对数据进行基本的观察

raw_pd.head(5) # 查看数据基本信息(前5行)
raw_pd.tail(5) # 查看末尾5行
raw_pd.sample(5) # 随机抽取5行查看
raw_pd.dtypes # 查看每列数据类型
raw_pd.columns    #查看列名
raw_pd.info()     #查看各字段的信息
raw_pd.shape      #查看数据集行列分布,几行几列
raw_pd.describe() # 快速查看数据的基本统计信息

3、有关空值处理

空值:在pandas中的空值是""
缺失值:在dataframe中为NaN或者NaT(缺失时间),在series中为none或者nan

# 测试数据
raw_pd = pd.DataFrame({"name": ['aoo', 'boo', 'coo'],"college": [np.nan, 'SACT', 'AACT'],"birth_date": [pd.NaT, pd.Timestamp("2000-10-01"),pd.NaT]})

3.1 行的空值处理

"""
axis:0或者'index'代表行操作(默认)  1或者'column':列操作
how:any-只要有空值就删除(默认),all-全部为空值才删除
inplace:False-返回新的数据集(默认),True-在愿数据集上操作
"""# 使用频率高:查看name列中,有多少行为空值行,value_counts其实是一个统计方法
raw_pd['name'].isnull().value_counts()# 使用频率高:any表示行的任意一列有空值,则删除该行;all表示该行全部为空,则删除
raw_pd.dropna(axis=0, how='any', inplace=True)# 行的任意一列有空值,且出现2个空值才删除这些行。例如该行有3列,其中2列都是为空,那么可以删掉该行。
使用频率低:raw_pd.dropna(axis=0, how='any',thresh=2, inplace=True)

3.2 列的空值处理

# 使用频率高:指定某几列,若这些列中出现了空值,则直接删除所在行
raw_pd.dropna(subset=['name', 'birth_date'],inplace=True)

3.3 空值的填充

最简单的用法,对全部数据记录里面的空值填充指定值

df.fillna(value=‘bar’)

频繁使用:对指定列的空值进行填充

raw_pd['name']=raw_pd['name'].fillna(value='bar')

高级填充方式
使用与空值单元相邻近的值来填充。该用法一般用在大量数据统计分析的场景或者图像的像素值填充、实验室的实验数据。相邻是指可以使用上下左右四个方向的值实现前向或者后向填充


DataFrame.fillna(value=None, method=None, axis=None, inplace=False, limit=None, downcast=None, **kwargs)method : {‘backfill’, ‘bfill’, ‘pad’, ‘ffill’, None}, default NoneMethod to use for filling holes in reindexed Series pad / ffill:
propagate last valid observation forward to next valid backfill / bfill: use NEXT valid observation to fill gapaxis : {0 or ‘index’, 1 or ‘columns’}
limit:限制填充的个数

这里使用比较频繁的是纵向填充,因为纵向代表的是列,从相邻样本的同一特征中填值,对每列的空值实施前项或者后项填充。

df.fillna(method='ffill') or df.fillna(method=‘bfill’)

3.4 空值使用所在列或者所在行的均值、中位数来填补

这里以均值填充为例,当然也可以用该列的预测值填充

mean_value = df['age'].mean()
df['age'].fillna(mean_value, inplace=True)

4、dataframe 取(定位)数据的操作

4.1 按给定列名取数,类似字典操作:df[‘列名’]

raw_pd= raw_pd['name']

取出多列数据,入参为包含多个字段的list:[‘name’,‘college’]

raw_pd[['name','college']]

4.2 按行默认的行索引号选取数据:df.loc

df = pd.DataFrame({"name": ['aoo', 'boo', 'coo'],"college": [np.nan, 'SACT', 'AACT'],"birth_date": [pd.NaT, pd.Timestamp("2000-10-01"),pd.NaT]})
# 查看该df的行索引
df.index
RangeIndex(start=0, stop=3, step=1)# 打印                  birth_date  college     name
0   NaT     NaN     aoo
1   2000-10-01  SACT    boo
2   NaT     AACT    coo # 这里的0,1,2就是pandas默认给加载的数据提供的行索引号

按索引取数据,跟列表使用slice切片获取数据的用法一致
df.loc[1] 获取行索引1的行数据,df.loc[1:2]获取1到2行数据

若行索引号不是int,例如将以上数据的默认index序列,改成字符索引序列

df.index=['a','b','c']
# 打印birth_date  college     name
a   NaT     NaN     aoo
b   2000-10-01  SACT    boo
c   NaT     AACT    coo

获取索引为b的数据:df.loc[‘b’]
或者索引为b、c的数据:df.loc[[‘b’,‘c’]]

4.3 按给定列名以及行索引取出数据

例如取出college列的b、c行数据

df.loc[['b','c'],'college']

例如取出college列、birth_date列的b、c行数据

df.loc[['b','c'],['college','birth_date']]
# 打印college     birth_date
b   SACT    2000-10-01
c   AACT    NaT

4.4 df.iloc利用index获取行数据或者列数据

df.iloc只能使用整型切片获取数据:例如df.iloc[0:10]
而df.loc可以使用字符型索引等来取数

5、通过复杂规则取数

在sql中经常会在where子句使用筛选条件:
select * from emp e where e.age>20 and e.dep_name=‘dev’ and e.city<>‘foo’
在pandas里面则使用方式如下:
单个筛选条件

df[df['age'] > 20]
或者
df.loc[df['age']>20]

多个筛选条件

df[(df['age'] > 20)&(df['dep_name']=='dev')&~(df['city']=='foo')]

使用isin方法

df[df['city'].isin(['foo','bar'])]

根据时间范围取值

# 从Excel加载的日期,如果格式不对,有可能是object类型,需将其转为datetime64[ns]类型,否则无法进行日期筛选比较
df['date_col']= df.to_datetime(df['date_col'])
start_time=datetime.datetime(2017,2,1) #或者pd.Timestamp('2017-02-01')
end_time=datetime.datetime(2017,2,14) #或者pd.Timestamp('2017-02-14')
# 注意以上的实际范围其实是 2017-02-01 00:00:00 ~2017-02-14 00:00:00
# 或者截止到当天最后一秒
end_time=datetime.datetime(2017,2,14,23,59,59) # 查找指定时间范围内的数据行
filter_df=df[(df['start_time']>=start_time) & (df['end_time']<=end_time)]

还有另外这一种方式是选择一个时间列,变将其设为当前df的时间索引,

常用:根据某个字段,取出获取删除其值出现频率排在前n的数据行

#  对name字段进行group_by
groupby_df=df.groupby('name')
# groupby_df:<pandas.core.groupby.DataFrameGroupBy object at 0x0000000010190C18>resl_df=groupby_df['name'].count()
# resl_df 就像透视表的数据形式
name
foo    10
bar    5
coo    4
dee    2
Name: bar, dtype: int64# 找name字段里,字符出现频率排在前2位,例如上述的例子:foo,bar。按降序返回一个python的列表
top_2_list=resl_df.sort_values(ascending=False).head(2)
print(top_2_list)
['foo','bar']# 将出现频率排在前2的内容拼接成用于正则匹配的字符串
pattern_str='|'.join(top_2_list)# 使用pandas提供的正则方法,剔除name字段中出现频率排在前2的数据行
filtered_df= df[~df['name'].str.contains(pattern_str, case=False, na=False,regex=True)]

使用时间索引选取数据行
个人认为,这种方式是时间选取数据场景最高效的手段
例如有数据df,其中create_date是该df唯一的日期字段,通常做法:
新增一列命名为back_up_date,用于备份create_date
df['back_up_date']=df['create_date']
将crete_date置为该df的时间索引
df=df.set_index('create_date')
当时间索引设置后,那么根据时间筛选数据将变得异常简单
取2000年的数据行
df['2000']
取2000年到2019年的数据行
df['2000':'2019']
某天具体时间到某天具体时间的数据行
df['2015-03-15 11:11:10':'2015-05-15 10:30:00']
有关pandas时间的专题,官方文档给出了非常详细的用法示例,这里不再赘述,timeseries链接

6、调整列位置、列的增、删

交换birth_date和college列的位置

df[['birth_date','college']]=df[['college','birth_date']]

删除指定列

df.drop(columns=['B', 'C'])

删除指定行,使用行索引

df.drop([0, 1])

删除重复行:df.drop_duplicates

直接删除重复行:

df.drop_duplicates()

删除name列、age列存在重复的行

df.drop_duplicates(['name','age'],keep='first',inplace=True)

请注意:以上删除行的操作,会破坏df原有的0到n的连续索引,例如原行索引为:0,1,2,3…n,其中索引1,2为空行,删除空行后,df的索引变为0,3…n,显然不连续,因此需要重置索引:df.reset_index(drop=True),重置后,索引变为0,1,2,3…n

7、单元格的字符相关处理

例如有字段app_id,有部分值字符串为数字:‘12331’,需转成int64
有部分值为字符加数字:‘TD12331’,去掉字符TD并转成int64
有些值为非id例如:‘ # llsd’,需对此类值用固定数值填充。因此需要对其统一处理成整型id
使用replace方法去掉值里面的TD字符串

df['app_id'].replace('TD','',regex=True,inplace=True)

使用apply方法通过定义简单的lambda去掉值里面的TD字符串

df['app_id']=df['app_id'].apply(lambda:item:item.replace('TD',''))

其实apply才是终极方法,适用各种自定义的数据行或者列的处理,例如对同一列的值有多种判断需要处理,则可以在外部定义要处理的函数,再用apply广播到该列的每个cell中。例如上面的例子:如果单元格数值含有TD则去掉TD字符保留其数值部分,如果单元格出现非数值,则将其设为NaN空值

def filter_id(cell):if re.match('\d{3}',cell):return cellelif re.match('TD',cell):return re.sub('TD','',cell)else:return np.nandf['app_id']=df['app_id'].apply(filter_id)

apply方法另外一种常用的方式:对数值进行分级,例如10<item<30为D,30<=item<60为C,60<=item<90为B。此外,货币进行转化、时间转换也是常用的场景

def level(item):if 10<=item<30:return 'D'elif 30<=item<60:return 'C'elif 60<=item<90:return 'B'else: return 'A'df['level']=df['level'].apply(level)

使用astype转成整型id号,具体其他数据类型不再列出。astype要求整列数据是完整的同一数据类型

df['app_id']=df['app_id'].astype('int64')

使用频繁:使用pandas.Series.str.contains方法处理列的值

Series.str.contains(pat, case=True, flags=0, na=nan, regex=True)
pat : str
Character sequence or regular expression.
case : bool, default True
If True, case sensitive.
flags : int, default 0 (no flags)
Flags to pass through to the re module, e.g. re.IGNORECASE.
na : default NaN
Fill value for missing values.
regex : bool, default True
If True, assumes the pat is a regular expression.
If False, treats the pat as a literal string.

删除name列中含有foo字符串的行,默认使用正则匹配
df=df[~df[‘name’].str.contains(‘foo’, case=false, flags=re.IGNORECASE, na=False)]

或者使用正则匹配
df=df[~df[‘name’].str.contains(’^foo’, case=false, flags=re.IGNORECASE, na=False)]

8、有关遍历行的处理

单表处理,请勿使用循环!! 效率很低!有apply方法足以,底层是矩阵操作。

遍历行,一般用在两个表之间,表A字段’date’与表B字段’date‘的比较
使用iterrows遍历行
iterate over DataFrame rows as (index, Series) pairs.

# 这种方式可以把索引和行数据遍历出,其中row的数据结构为nametuple
for index,row in df.iterrows():print(index,row)# 这种方式其实就是itertuples(index=False)的遍历
for _,row in df.iterrows():print(row.A,row.B)

使用itertuples遍历行
Iterate over DataFrame rows as namedtuples of the values.

s = pd.Series(pd.date_range('2012-1-1', periods=10, freq='D'))
td = pd.Series([pd.Timedelta(days=i) for i in range(10)])
df = pd.DataFrame({'A': s, 'B': td})
#这种方式,取出的每行为nametuple
for row in df.itertuples(index=False):print(row.A,row.B)

使用iteritems遍历列
这种方式以横向遍历列数据,每次返回该列名和该列Series

9、DataFrame和DataFrame合并、关联查询等

9.1 DataFrame和DataFrame合并

合并具有相同结构的df
将多个DataFrame按垂直方向或者水平方向合并:这种场合使用批量处理具有相同字段结构的多份报表或数据源

# 默认是按垂直方向合并三个子df
frames = [df1, df2, df3]
result = pd.concat(frames)# 在合并后,还可以为每个子df设定相应key
result = pd.concat(frames, keys=['foo', 'bar', 'cee'])# 利用上面key,可以一次性取回合并前的df1
df1=result.loc['foo']

合并字段不同的df

9.2 DataFrame和DataFrame之间的关联查询

因为关联查询基本是数据分析里面重要的、使用频繁的需求,例如实现报表1和报表的用vlookup关联查询、sql中多个表的关联查询(内连接、左连接、右连接、全连接)。pandas的doc官方文档在这部分的内容已经非常详细,并且有相应的关联前后的图文说明,本文不再一一赘述,仅给出简单的关联用法。
以内连接为例:
实现类似sql使用两表的多个外键关联:

select t1.*,t2.* from t1,t2 where t1.a=t2.a
and t1.b=t2.b
and t1.c=t2.c

pandas的方式

df1.merge(df2, on=[ key1 ,  key2 ,  key ])

使用单个字段(外键)关联两表

df1.merge(df2, on='dept_id')

10、groupby基本用法

groupby可以说面对不同的数据需求,有不同用法,对sql熟悉的人应该无需多说。这里仅给出一些简单用法。

按季度分组,提取每个分组前n个数据行

def top_n(df,n=3):return df[0:n]
# 这里的n是top_n自定义的关键字参数n,不是apply的参数
df.groupby('quarter').apply(top_n,n=3)

按产品种类分组,提取每个分组里最大值和最小值之差

# 每个产品种类的数值跨度范围,也即最大值减去最小值
def max_min(item):return item.max() - item.min()
df.groupby('prod').agg(max_min)

按产品种类分组,一次性取出每组的最值、均值、数值跨度范围,这里需要注意agg的入参为方法的列表,内置方法使用其字符名,自定义方使用其函数名

df.groupby('prod').agg(['mean','max','min',max_min])

Pandas数据预处理的常用函数相关推荐

  1. pandas数据预处理(字段筛选、query函数进行数据筛选、缺失值删除)、seaborn可视化分面图(facet)、seaborn使用Catplot可视化分面箱图(Faceted Boxplot)

    pandas数据预处理(字段筛选.query函数进行数据筛选.缺失值删除).seaborn可视化分面图(facet).seaborn使用Catplot可视化分面箱图(Faceted Boxplot) ...

  2. python对csv文件的处理,pandas 数据预处理csv,案例详细

    文章目录 csv文件的导入 CSV文件的导出 不导出行号和标签,可分别将index或header设置为False 使用columns参数设置想导出的列 数据清理分组 排序 删除 缺失值处理 缺失值的删 ...

  3. Pandas数据预处理与数据重塑案例

    Pandas数据预处理与数据重塑案例 前言   预处理是数据分析中不可缺少的一部分,我们日常得到的数据多半是规整的,只有得到想要的相应格式的数据,才能进行后续的探索性分析和建模.以下是我在一个小的项目 ...

  4. Pandas数据预处理|数据清理

    Pandas数据预处理(Data Preprocess)-数据清理 日期:2021/4/27 作者:就叫易易好了 注:本篇文章采用的数据集为"vgsales.csv",下载链接:h ...

  5. dplyr | 数据导入和预处理的常用函数

    在正式分析数据前,我们通常需要先预处理一下数据,比如筛选有效样本,定义变量格式,处理缺失值等,目的是把数据整理成比较清洁的形式,便于后续处理,而R的tidyverse系列工具包针对此提供了丰富多样的处 ...

  6. 超全面 pandas 数据预处理+数据概览 处理技巧整理(持续更新版)

    这篇文章主要是整理下使用pandas的一些技巧,因为经常不用它,这些指令忘得真的很快.前段时间在数模美赛中已经栽过跟头了,不希望以后遇到相关问题的时候还去网上查(主要是太杂了).可能读者跟我有一样的问 ...

  7. pandas数据预处理(标准化归一化、离散化/分箱/分桶、分类数据处理、时间类型数据处理、样本类别分布不均衡数据处理、数据抽样)

    1. 数值型数据的处理 1.1 标准化&归一化 数据标准化是一个常用的数据预处理操作,目的是处理不同规模和量纲的数据,使其缩放到相同的数据区间和范围,以减少规模.特征.分布差异等对模型的影响. ...

  8. frac函数_20个能够有效提高 Pandas数据分析效率的常用函数,附带解释和例子

    Pandas是一个受众广泛的python数据分析库.它提供了许多函数和方法来加快数据分析过程.pandas之所以如此普遍,是因为它的功能强大.灵活简单. 本文将介绍20个常用的 Pandas 函数以及 ...

  9. Pandas 数据预处理

    Pandas数据处理 一 概述 1.1 业务建模流程 将业务抽象为分类or回归问题 定义标签,得到y 选取合适的样本,并匹配出全部的信息作为特征的来源 特征工程 + 模型训练 + 模型评价与调优(相互 ...

最新文章

  1. 一文全览,深度学习时代下,复杂场景下的 OCR 如何实现?
  2. 大数据没有降温,已融入主流科技领域
  3. 每日一皮:周六了,想跟你说一句...
  4. 'module' object has no attribute 'scalar_summary'
  5. list contains方法_Java中给List去重的5种方法,谁的效率更高?
  6. 枚举类型(C# 编程指南)
  7. 多个left join 产生多个结果
  8. zabbix mysql 平台_监控平台-zabbix
  9. python进行气象数据分析_使用机器学习进行气象数据分析
  10. 深入理解 Tomcat(四)Tomcat 类加载器之为何违背双亲委派模型
  11. N002-认知C#中的字符串
  12. 用R和BioConductor进行基因芯片数据分析(三):计算median
  13. vNext之旅(1):从概念和基础开始
  14. 微信支付将为O2O画上句号
  15. lammps教程:EAM势函数设置详解
  16. 公众号常用的排版软件有哪些?
  17. 运筹优化算法工程师面试汇总
  18. 识别图片验证码内容 -- ddddocr识别
  19. 我的后台Java面经(阿里、腾讯、头条、京东、IBM等)
  20. Redis高级特性RDB、AOF、事务、Stream、Pipeline和Lua脚本

热门文章

  1. matlab awgn矩阵,MATLAB中产生高斯白噪声,涉及到awgn和wgn函数
  2. Win32 键盘事件 - 击键消息、字符消息、插入符号(光标)
  3. 登录页面居中示例代码
  4. 做人的基本原则---如何正确做人
  5. 抖音文案怎么写吸引人情感,2021抖音经典短句
  6. Python-石头,剪刀,布
  7. 2018oracle市场份额,2018年中国ERP软件行业市场现状与竞争格局分析,ERP的管理范围继续扩大「图」...
  8. 决定代理ip网速的原因有哪些
  9. summary for matplotlib(cord in python)
  10. PTA题库函数递归 菲波那切数列(递归版)