Pandas数据分析学习笔记

前言

开刷Pandas数据分析,看起来很好理解,不过没做笔记没敲代码心里总是不安稳,所以复现下课程代码并演示其中遇到的问题,顺便水一水笔记好了

参考资料:

课程视频链接:Pandas数据分析从入门到实战

数据及代码示例:ant-learn-pandas: pandas学习课程代码仓库 (gitee.com)

一、数据读取

0. 数据类型

数据类型说明Pandas读取方法
csv, tsv, txt用逗号、tab或其它字符分割的文本文件read_csv
excelxls或xlsx文件read_excel
mysql关系型数据表read_sql

1. read_csv

1.1 读取csv文件

csv是以逗号分割的文本文件,如下:

userId,movieId,rating,timestamp
1,1,4.0,964982703
1,3,4.0,964981247
1,6,4.0,964982224
1,47,5.0,964983815

直接使用read_csv读取该文件

fpath = "../datas/ml-latest-small/ratings.csv"
# 读取
ratings = pd.read_csv(fpath)

1.2 指定分割符

已知access_pvuv.txt如下:

2019-09-10  139    92
2019-09-09  185    153
2019-09-08  123    59
2019-09-07  65     40
2019-09-06  157    98
2019-09-05  205    151
2019-09-04  196    167
2019-09-03  216    176
2019-09-02  227    148
2019-09-01  105    61

为read_csv添加参数delimiter (或seq) 指定分隔符,header=None表示没有第一行列名称

fpath = "../datas/crazyant/access_pvuv.txt"

pvuv = pd.read_csv(
    fpath,
    delimiter='\t',
    header=None,
    names=['date', 'pv', 'uv']
)

2. read_excel

fpath = "../datas/crazyant/access_pvuv.xlsx"
pvuv = pd.read_excel(fpath)
print(pvuv)

'''
输出结果
           日期   PV   UV
0  2019-09-10  139   92
1  2019-09-09  185  153
2  2019-09-08  123   59
3  2019-09-07   65   40
4  2019-09-06  157   98
5  2019-09-05  205  151
6  2019-09-04  196  167
7  2019-09-03  216  176
8  2019-09-02  227  148
9  2019-09-01  105   61
'''

3. read_sql

3.1 使用pymysql

连接数据库,选择编码方式

import pandas as pd
import pymysql

conn = pymysql.connect(
    host='localhost',
    user='root',
    password='password',
    database='dbname',
    charset='utf8'
)
table = pd.read_sql("select * from tbname", con=conn)
print(table)
'''
输出结果
   id                       preorder_traversal_string
0   1             4_2_1_0_#_#_#_3_#_#_8_7_#_#_11_#_#_
1   2  5_4_2_#_#_1_7_#_6_#_#_#_3_0_#_5_1_#_#_#_6_#_#_
2   3                  6_#_7_5_3_#_#_1_#_#_2_8_#_#_#_
'''

但是会报警告:

UserWarning: pandas only supports SQLAlchemy connectable (engine/connection) or database string URI or sqlite3 DBAPI2 connection. Other DBAPI2 objects are not tested. Please consider using SQLAlchemy.

这里建议我们使用SQLAlchemy

3.2 使用SQLAlchemy

import pandas as pd

from sqlalchemy import create_engine

host = "127.0.0.1"
user = "root"
password = "password"
database = "dbname"

engine = create_engine(f"mysql+pymysql://{user}:{password}@{host}/{database}")
sql = 'select * from tbname'
table = pd.read_sql(sql=sql, con=engine)

print(table)
'''
输出结果
   id                       preorder_traversal_string
0   1             4_2_1_0_#_#_#_3_#_#_8_7_#_#_11_#_#_
1   2  5_4_2_#_#_1_7_#_6_#_#_#_3_0_#_5_1_#_#_#_6_#_#_
2   3                  6_#_7_5_3_#_#_1_#_#_2_8_#_#_#_
'''

4. 查看数据格式

# 查看前几行数据,默认为5行
print(ratings.head())
'''
输出结果
   userId  movieId  rating  timestamp
0       1        1     4.0  964982703
1       1        3     4.0  964981247
2       1        6     4.0  964982224
3       1       47     5.0  964983815
4       1       50     5.0  964982931
'''

# 查看数据的形状,返回(行数、列数)
print(ratings.shape)

'''
输出结果
(100836, 4)
'''

# 查看列名列表
print(ratings.columns)
'''
输出结果
Index(['userId', 'movieId', 'rating', 'timestamp'], dtype='object')
'''

# 查看索引列
print(ratings.index)
'''
输出结果
RangeIndex(start=0, stop=100836, step=1)
'''

# 查看每列的数据类型
print(ratings.dtypes)
'''
输出结果
userId         int64
movieId        int64
rating       float64
timestamp      int64
dtype: object
'''

二、数据结构

1. Series

import pandas as pd

# 创建Series
s1 = pd.Series(list('abcd'))
print(s1)
'''
0    a
1    b
2    c
3    d
dtype: object
'''
# 指定索引创建Series
s2 = pd.Series(list('efgh'), index=list('abcd'))
print(s2)
print(s2.index)
'''
a    e
b    f
c    g
d    h
dtype: object
Index(['a', 'b', 'c', 'd'], dtype='object')
'''
# 字典创建Series
dict = {
    'a': 'e',
    'b': 'f',
    'c': 'g',
    'd': 'h'
}
s3 = pd.Series(dict)
print(s3)
'''
a    e
b    f
c    g
d    h
dtype: object
'''

2. DataFrame

import pandas as pd

# 字典创建DataFrame
data = {
        'state': ['Ohio', 'Ohio', 'Ohio', 'Nevada', 'Nevada'],
        'year': [2000, 2001, 2002, 2001, 2002],
        'pop': [1.5, 1.7, 3.6, 2.4, 2.9]
    }
df = pd.DataFrame(data)

print(df)
'''
    state  year  pop
0    Ohio  2000  1.5
1    Ohio  2001  1.7
2    Ohio  2002  3.6
3  Nevada  2001  2.4
4  Nevada  2002  2.9
'''
# 输出DataFrame的索引、列标签以及数据类型
print(df.index, '\n\n', df.columns, '\n\n', df.dtypes)
'''
RangeIndex(start=0, stop=5, step=1)

 Index(['state', 'year', 'pop'], dtype='object')

 state     object
year       int64
pop      float64
dtype: object
'''

三、查询数据

0. 查询方法

  1. df.loc :基于标签索引,结果包含最后一个标签的值
  2. df.iloc:基于位置索引,结果不包含最后一个位置的值
  3. df.where
  4. df.query

本节主要介绍df.loc

1. 数据预处理

import pandas as pd

# 数据预处理
df = pd.read_csv("../datas/beijing_tianqi/beijing_tianqi_2018.csv")

print(df.head())
'''
          ymd bWendu yWendu tianqi fengxiang fengli  aqi aqiInfo  aqiLevel
0  2018-01-01     3℃    -6℃   晴~多云       东北风   1-2级   59       良         2
1  2018-01-02     2℃    -5℃   阴~多云       东北风   1-2级   49       优         1
2  2018-01-03     2℃    -5℃     多云        北风   1-2级   28       优         1
3  2018-01-04     0℃    -8℃      阴       东北风   1-2级   28       优         1
4  2018-01-05     3℃    -6℃   多云~晴       西北风   1-2级   50       优   
'''
# 设定索引为日期,方便按日期筛选
df.set_index('ymd', inplace=True)
# 替换掉温度的后缀℃
df.loc[:, "bWendu"] = df["bWendu"].str.replace("℃", "").astype('int32')
df.loc[:, "yWendu"] = df["yWendu"].str.replace("℃", "").astype('int32')
# df[df.columns["bWendu"]] = df["bWendu"].str.replace("℃", "").astype('int32')
# df[df.columns["yWendu"]] = df["yWendu"].str.replace("℃", "").astype('int32')
print(df.head())
'''
            bWendu  yWendu tianqi fengxiang fengli  aqi aqiInfo  aqiLevel
ymd
2018-01-01       3      -6   晴~多云       东北风   1-2级   59       良         2
2018-01-02       2      -5   阴~多云       东北风   1-2级   49       优         1
2018-01-03       2      -5     多云        北风   1-2级   28       优         1
2018-01-04       0      -8      阴       东北风   1-2级   28       优         1
2018-01-05       3      -6   多云~晴       西北风   1-2级   50       优    
'''

这里会报一个警告:

 DeprecationWarning: In a future version, `df.iloc[:, i] = newvals` will attempt to set the 
 values inplace instead of always setting a new array. To retain the old behavior, use either
 `df[df.columns[i]] = newvals` or, if columns are non-unique, `df.isetitem(i, newvals)`

2. 按数值、列表、区间查询

# 得到单个值
single_value = df.loc['2018-01-03', 'bWendu']
# 得到一列/一行
s1 = df.loc['2018-01-03', ['bWendu', 'yWendu']]
s2 = df.loc[['2018-01-03', '2018-01-04', '2018-01-05'], 'bWendu']
# 得到DataFrame
df2 = df.loc[['2018-01-03','2018-01-04','2018-01-05'], ['bWendu', 'yWendu']]
# 按区间查询
df3 = df.loc['2018-01-03':'2018-01-05', 'bWendu':'fengxiang']

3. 条件查询

# 查询最高温度小于30度,并且最低温度大于15度,并且是晴天,并且天气为优的数据
df4 = df.loc[(df["bWendu"] <= 30) & (df["yWendu"] >= 15)
        & (df["tianqi"] == '晴') & (df["aqiLevel"] == 1), :]
print(df4)
'''
            bWendu  yWendu tianqi fengxiang fengli  aqi aqiInfo  aqiLevel
ymd
2018-08-24      30      20      晴        北风   1-2级   40       优         1
2018-09-07      27      16      晴       西北风   3-4级   22       优         1
'''

其中,条件表达式返回的是一个布尔值的Series

# 观察条件表达式
print(df["yWendu"] < -10)
'''
2018-01-01    False
2018-01-02    False
2018-01-03    False
2018-01-04    False
2018-01-05    False
              ...
2018-12-27     True
2018-12-28     True
2018-12-29     True
2018-12-30     True
2018-12-31    False
Name: yWendu, Length: 365, dtype: bool
'''

4. 函数查询

# 直接写lambda表达式
df5 = df.loc[lambda df : (df["bWendu"] <= 30) & (df["yWendu"] >= 15), :]
# 编写自己的函数,查询9月份,空气质量好的数据
def query_my_data(df):
    return df.index.str.startswith("2018-09") & (df["aqiLevel"] == 1)

df6 = df.loc[query_my_data, :]

四、新增数据列

1. 直接赋值

df.loc[:, 'wencha'] = df['bWendu'] - df['yWendu']

2. df.apply

传入一个函数并选定axis:

  1. 当axis=1,函数的参数为一行的Series(常用)
  2. 当axis=0,函数的参数为一列的Series
def get_wendu_type(x):
    if x["bWendu"] > 33:
        return '高温'
    if x["yWendu"] < -10:
        return '低温'
    return '常温'

df.loc[:, "wendu_type"] = df.apply(get_wendu_type, axis=1)

3. df.assign

df.assign总是会创建一个新的copy

利用lambda表达式,处理原来的数据得到新列

# 可以同时添加多个新的列
df.assign(
    yWendu_huashi = lambda x : x["yWendu"] * 9 / 5 + 32,
    # 摄氏度转华氏度
    bWendu_huashi = lambda x : x["bWendu"] * 9 / 5 + 32
)

4. 条件选择分组后赋值

# 先创建空列(这是第一种创建新列的方法)
df['wencha_type'] = ''

错误示例:

df.loc[df["bWendu"]-df["yWendu"]>10]["wencha_type"] = "温差大"

df.loc[df["bWendu"]-df["yWendu"]<=10]["wencha_type"] = "温差正常"

两个[]的链式操作相当于

df.get(condition).set(wen_cha)

这里get得到的结果可能是view也可能是copy,存在歧义

正确示范:

df.loc[df["bWendu"]-df["yWendu"]>10, "wencha_type"] = "温差大"

df.loc[df["bWendu"]-df["yWendu"]<=10, "wencha_type"] = "温差正常"

五、聚合查询

1. describe输出统计结果

# 一下子提取所有数字列统计结果
df.describe()
           bWendu      yWendu         aqi    aqiLevel      wencha
count  365.000000  365.000000  365.000000  365.000000  365.000000
mean    18.665753    8.358904   82.183562    2.090411   10.306849
std     11.858046   11.755053   51.936159    1.029798    2.781233
min     -5.000000  -12.000000   21.000000    1.000000    2.000000
25%      8.000000   -3.000000   46.000000    1.000000    8.000000
50%     21.000000    8.000000   69.000000    2.000000   10.000000
75%     29.000000   19.000000  104.000000    3.000000   12.000000
max     38.000000   27.000000  387.000000    6.000000   18.000000

describe只能得到数值列的统计结果

2. 非数值列统计

2.1 unique唯一去重

print(df['tianqi'].unique())
['晴~多云' '阴~多云' '多云' '阴' '多云~晴' '多云~阴' '晴' '阴~小雪' '小雪~多云' '小雨~ 阴' '小雨~雨夹雪'
 '多云~小雨' '小雨~多云' '大雨~小雨' '小雨' '阴~小雨' '多云~雷阵雨' '雷阵雨~多云' '阴~ 雷阵雨' '雷阵雨'
 '雷阵雨~大雨' '中雨~雷阵雨' '小雨~大雨' '暴雨~雷阵雨' '雷阵雨~中雨' '小雨~雷阵雨' '雷 阵雨~阴' '中雨~小雨'
 '小雨~中雨' '雾~多云' '霾']

2.2 value_counts按值计数

print(df['wencha_type'].value_counts())
温差正常    187
温差大     178
Name: wencha_type, dtype: int64

3. 协方差和相关系数

print(df.cov(), '\n\n', df.corr())
              bWendu      yWendu          aqi   aqiLevel     wencha
bWendu    140.613247  135.529633    47.462622   0.879204   5.083614
yWendu    135.529633  138.181274    16.186685   0.264165  -2.651641
aqi        47.462622   16.186685  2697.364564  50.749842  31.275937
aqiLevel    0.879204    0.264165    50.749842   1.060485   0.615038
wencha      5.083614   -2.651641    31.275937   0.615038   7.735255

             bWendu    yWendu       aqi  aqiLevel    wencha
bWendu    1.000000  0.972292  0.077067  0.071999  0.154142
yWendu    0.972292  1.000000  0.026513  0.021822 -0.081106
aqi       0.077067  0.026513  1.000000  0.948883  0.216523
aqiLevel  0.071999  0.021822  0.948883  1.000000  0.214740
wencha    0.154142 -0.081106  0.216523  0.214740  1.000000

六、缺失值处理

1. 处理方式

Pandas使用这些函数处理缺失值:

  • isnull和notnull:检测是否是空值,可用于df和series
  • dropna:丢弃、删除缺失值
    • axis : 删除行还是列,{0 or ‘index’, 1 or ‘columns’}, default 0
    • how : 如果等于any则任何值为空都删除,如果等于all则所有值都为空才删除
    • inplace : 如果为True则修改当前df,否则返回新的df
  • fillna:填充空值
    • value:用于填充的值,可以是单个值,或者字典(key是列名,value是值)
    • method : 等于ffill使用前一个不为空的值填充forword fill;等于bfill使用后一个不为空的值填充backword fill
    • axis : 按行还是列填充,{0 or ‘index’, 1 or ‘columns’}
    • inplace : 如果为True则修改当前df,否则返回新的df

2. 数据清洗示例

image.png

2.1 检测空值

# 跳过前面两空行
studf = pd.read_excel("../datas/student_excel/student_excel.xlsx", skiprows=2)

# 检测空值
print(studf.isnull())
    Unnamed: 0     姓名     科目     分数
0         True  False  False  False
1         True   True  False  False
2         True   True  False  False
3         True   True   True   True
4         True  False  False  False
5         True   True  False   True
6         True   True  False  False
7         True   True   True   True
8         True  False  False  False
9         True   True  False  False
10        True   True  False  False

2.2 dropna示例

# 删除全为空的行和列
studf.dropna(axis=1, how='all', inplace=True)
studf.dropna(axis=0, how='all', inplace=True)

print(studf)
     姓名  科目    分数
0    小明  语文  85.0
1   NaN  数学  80.0
2   NaN  英语  90.0
4    小王  语文  85.0
5   NaN  数学   NaN
6   NaN  英语  90.0
8    小刚  语文  85.0
9   NaN  数学  80.0
10  NaN  英语  90.0

2.3 fillna示例

# 将空的分数填充为0
# 将空的姓名填充为上一个值
studf['分数'].fillna(value=0, inplace=True)
studf['姓名'].fillna(method='ffill', inplace=True)

print(studf)
    姓名  科目    分数
0   小明  语文  85.0
1   小明  数学  80.0
2   小明  英语  90.0
4   小王  语文  85.0
5   小王  数学   0.0
6   小王  英语  90.0
8   小刚  语文  85.0
9   小刚  数学  80.0
10  小刚  英语  90.0

七、数据排序

1. 排序方法

  1. Series的排序:
    Series.sort_values(ascending=True, inplace=False)
    参数说明:
  • ascending:默认为True升序排序,为False降序排序
  • inplace:是否修改原始Series
  1. DataFrame的排序:
    DataFrame.sort_values(by, ascending=True, inplace=False)
    参数说明:
  • by:字符串或者List<字符串>,单列排序或者多列排序
  • ascending:bool或者bool的列表,升序还是降序,如果是list对应by的多列
  • inplace:是否修改原始DataFrame

2. 排序示例

# Series的排序
print(df['aqi'].sort_values())
ymd
2018-09-29     21
2018-10-09     21
2018-09-07     22
2018-09-30     22
2018-10-29     22
             ...
2018-11-14    266
2018-03-13    287
2018-04-02    287
2018-03-14    293
2018-03-28    387
Name: aqi, Length: 365, dtype: int64
# DataFrame的排序
df.sort_values(by=['aqi', 'bWendu'], ascending=[False, True], inplace=True)
print(df[['aqi', 'bWendu']])
            aqi  bWendu
ymd
2018-03-28  387      25
2018-03-14  293      15
2018-03-13  287      17
2018-04-02  287      26
2018-11-14  266      13
...         ...     ...
2018-10-29   22      15
2018-09-30   22      19
2018-09-07   22      27
2018-10-09   21      15
2018-09-29   21      22

八、字符串处理

0. Pandas的str

Pandas的字符串处理:

  1. 使用方法:先获取Series的str属性,然后在属性上调用函数;
  2. 只能在字符串列上使用,不能数字列上使用;
  3. Dataframe上没有str属性和处理方法
  4. Series.str并不是Python原生字符串,而是自己的一套方法,不过大部分和原生str很相似;

1. 基础用法

获取str属性,并调用各种方法,如replace, isnumeric, len

print(df['wencha_type'].str.len())
ymd
2018-03-28    3
2018-03-14    4
2018-03-13    3
2018-04-02    3
2018-11-14    4
             ..
2018-10-29    3
2018-09-30    4
2018-09-07    3
2018-10-09    3
2018-09-29    3
Name: wencha_type, Length: 365, dtype: int64

2. 条件查询

或使用contains, startswith等得到bool的Series做条件查询

print(df.loc[df['tianqi'].str.startswith('多云'), ['tianqi', 'fengxiang']])
           tianqi fengxiang
ymd
2018-03-28   多云~晴        东风
2018-03-14   多云~阴       东北风
2018-04-02     多云        北风
2018-11-14     多云        南风
2018-11-26     多云       东南风
...           ...       ...
2018-01-25     多云       东北风
2018-10-10   多云~晴       西北风
2018-02-03     多云        北风
2018-09-30     多云       西北风
2018-10-09   多云~晴       西北风

3. 正则表达式

由于Series.str天然支持正则表达式,示例如下:

匹配字符集合并做替换:

# 添加新列
def get_nianyueri(x):
    year,month,day = x["ymd"].split("-")
    return f"{year}{month}{day}日"
df["中文日期"] = df.apply(get_nianyueri, axis=1)

# 尝试将 年 月 日 去除
df.loc[:, '中文日期'] = df['中文日期'].str.replace('[年月日]', '')
print(df['中文日期'])
86     20180328
72     20180314
71     20180313
91     20180402
317    20181114
         ...
301    20181029
272    20180930
249    20180907
281    20181009
271    20180929
Name: 中文日期, Length: 365, dtype: object

捕获组提取数据:

extracted_fengli = df['fengli'].str.extract(r'(\d)-(\d)')
print(extracted_fengli.head())
     0  1
86   1  2
72   1  2
71   1  2
91   1  2
317  1  2
..  .. ..
301  3  4
272  4  5
249  3  4
281  4  5
271  3  4

九、索引

0. 索引的作用

选择恰当的索引可以加速查询性能

  1. 当索引是唯一的时,Pandas会用哈希表优化性能,时间复杂度为O(1)
  2. 当索引不唯一,但是单调时,Pandas会使用二分查找,时间复杂度为O(log n)
  3. 当索引既不唯一且不单调时,Pandas只能遍历,时间复杂度为O(n)

因此,我们要判断当前索引是否为以上类型,尽可能选择唯一的索引,单调次之

1. 选择索引示例

原始数据如下:

print(df.head())
   userId  movieId  rating  timestamp
0       1        1     4.0  964982703
1       1        3     4.0  964981247
2       1        6     4.0  964982224
3       1       47     5.0  964983815
4       1       50     5.0  964982931

判断每一列是否存在唯一约束:

print(df.nunique() == len(df))
userId       False
movieId      False
rating       False
timestamp    False
dtype: bool

判断每一列是否单调:


# 使用这一句会报FutureWarning
# is_monotonic = df.apply(lambda x: x.is_monotonic)

is_monotonic_increasing = df.apply(lambda x: x.is_monotonic_increasing)
is_monotonic_decreasing = df.apply(lambda x: x.is_monotonic_decreasing)
print(is_monotonic_increasing, '\n\n', is_monotonic_decreasing)
userId        True
movieId      False
rating       False
timestamp    False
dtype: bool

 userId       False
movieId      False
rating       False
timestamp    False
dtype: bool

2. 设置索引示例

DataFrame.set_index(keys, append=False, drop=True, inplace=False)

keys代表被用作索引的列

append代表是否保留原来的索引

drop表示是否将指定的列在原数据列中删除

inplace表示是否在原数据上修改

df.set_index('userId',append=True, drop=False, inplace=True)
print(df.head())
          userId  movieId  rating  timestamp
  userId
0 1            1        1     4.0  964982703
1 1            1        3     4.0  964981247
2 1            1        6     4.0  964982224
3 1            1       47     5.0  964983815
4 1            1       50     5.0  964982931

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/554601.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Halo自定义页面

在使用Halo后台维护项目&#xff0c;有的页面是固定的&#xff0c;但内容需要一些自定义样式&#xff0c;内容动态编辑生成&#xff0c;这个时候就需要自定义页面; Halo版本 版本&#xff1a;2.121.首先在theme.yaml中添加自定义页面并指定文件名 spec:customTemplates:page:…

面试题集中营—GC日志简析及频繁GC的调优

如何查看GC日志 有两种方式查看GC日志&#xff0c;一种是动态命令行查看 jstat -gc <pid> 300 5 第二种就是在JVM参数中增加打印的参数&#xff0c;如下&#xff1a; -XX:PrintGCDetails -XX:PrintGCTimeStamps 表示打印每次GC的日志以及GC发生的时间 -Xloggc:gc.log …

如何解决PPT中获取加载项是灰色的,无法链接到Power BI的问题?

问题描述&#xff1a; 最近有朋友留言询问:“在尝试之前我发布的如何在PPT中展示Power BI报告的操作步骤的时候&#xff0c;想要在PPT中展示Power BI报告&#xff1f;只需这样做&#xff01; (qq.com) 碰到在PowerPoint中【获取加载项选项】是灰色&#xff0c;无法链加载Powe…

WordPress网站上添加看板娘

续接上篇——基于LNMP部署wordpress-CSDN博客 目录 一.下载并解压 二.设置头文件 修改header.php 修改配置文件footer.php 三.将你设置的主题包上传到/usr/share/nginx/html/wp-content这个目录里 四.扩展——将看板娘修改到左侧 一.下载并解压 [rootaliyun ~]# wget htt…

技术分享 | app测试中常用的Android模拟器

Emulator Emualor 是 Android Studio 自带的模拟器&#xff0c;是官方提供的工具&#xff0c;Android 开发最常使用的就是这一款。 它功能非常齐全&#xff0c;电话本、通话等功能都可正常使用。用户可以使用键盘输入&#xff0c;鼠标点击模拟器按键输入&#xff0c;甚至还可…

安卓投屏延时数据如何测试,测试工具如何写?

背景&#xff1a; 投屏其实在android等使用场景非常非常多&#xff0c;比如现在火爆小米汽车的车机&#xff0c;上面涉及到手机和车机互联画面相关都是属于投屏范围。这种跨设备的投屏场景&#xff0c;流畅的体验是最重要的&#xff0c;这里就会要求投屏中最重要的一个性能指标…

Nerf技术原理

Neural Radiance Fields (NeRF) 是一种3D场景重建技术,用于从一组稀疏的2D图像创建高质量的3D模型。这一技术基于深度学习,通过训练一个神经网络来模拟场景的体积密度和颜色分布,实现在新的视角下渲染出高质量的3D图像。 NeRF的核心原理 NeRF的核心在于使用一个全连接的神经…

开源事件通知库libevent及网络连接管理模块bufferevent详解

目录 1、libevent介绍 1.1、什么是libevent&#xff1f; 1.2、libevent特点 1.3、网络连接管理模块bufferevent 2、bufferevent有什么用&#xff1f; 3、bufferevent的整体设计与实现细节 3.1、整体概况 3.2、evbuffer与bufferevent 3.3、defer callback 4、bufferev…

听说英伟达和诺和诺德要共建医药研发超算,超算安腾默默笑了

继黄仁勋公开发表“生命科学才是未来”的观点后&#xff0c;英伟达押注生物计算赛道又有新动作。日前&#xff0c;诺和诺德基金会宣布将出资和英伟达合作&#xff0c;在丹麦建造一台专注于生成式AI应用的超级计算机&#xff0c;以推动医疗保健、生命科学和绿色转型领域的研究与…

【JavaSE进阶】08-反射机制 09-注解

1 反射机制 a) 反射的基本概念 b) Java中的类反射 c) 安全性和反射 d) 反射的两个缺点 1.1 反射的基本概念 反射的概念是由 Smith 在 1982 年首次提出的&#xff0c;主要是指程序可以访问、检测和修改它本身状 态或行为的一种能力, 并能根据自身行为的状态和结果&#…

六、项目发布 -- 2. 数据库环境准备

之前我们是采用mock方式获取这些接口&#xff0c;也就是这些接口的数据其实是固定的&#xff0c;现在我们将从数据库中来获取这些数据并且在界面上进行展示。 1、数据库环境准备 到MYSQL官网上&#xff0c;主要下载服务端&#xff0c;社区版是免费的&#xff0c;安装好MYSQL …

结构体(C语言)

“点赞&#xff0c;留言&#xff0c;收藏&#xff0c;关注” 就是对阿林最大的支持 1.自定义类型 什么是自定义类型&#xff1f;C语言中有一些自带的数据类型&#xff0c;比如说char&#xff0c;int&#xff0c;float&#xff0c;double&#xff0c;long等数据类型就是C语言的…

目标检测——标注鱼类数据集

一、重要性及意义 鱼类的检测在多个领域都表现出其重要性和意义。以下是几个主要方面的阐述&#xff1a; 首先&#xff0c;从食品安全和营养价值的角度来看&#xff0c;鱼类作为人们日常生活中的重要蛋白质来源&#xff0c;其质量和安全性备受关注。鱼类营养成分检测能够评估…

C++异步回调示例:多线程执行任务,主线程通过回调监测任务状态

1、回调函数 回调函数定义&#xff1a;把函数的指针或者地址作为参数传递给另一个参数&#xff0c;当这个指针被用来调用其所指向的函数时&#xff0c;那么这就是一个回调的过程&#xff0c;这个被回调的函数就是回调函数。回调函数不是由该函数的实现方直接调用&#xff0c;而…

反转二叉树(力扣226)

解题思路&#xff1a;用队列进行前序遍历的同时把节点的左节点和右节点交换 具体代码如下&#xff1a; class Solution { public:TreeNode* invertTree(TreeNode* root) {if (root NULL) return root;swap(root->left, root->right); // 中invertTree(root->left)…

oracle 数据库 迁移 mysql

将 Oracle 数据库迁移到 MySQL 是一项复杂的任务&#xff0c;因为这两种数据库管理系统具有不同的架构、语法和功能。下面是一个基本的迁移步骤&#xff0c;供你参考&#xff1a; 步骤一&#xff1a;评估和准备工作 1.评估数据库结构&#xff1a;仔细分析 Oracle 数据库的结构…

让15万的车也配激光雷达,速腾发布中长距「千元机」MX

‍作者 |老缅 编辑 |德新 4月15日&#xff0c;国内头部激光雷达公司速腾聚创发布了新一代中长距激光雷达MX。 相比较其产品配置&#xff0c;最令人惊喜的是它的价格。 「MX将以低于200美元的价格作为基础&#xff0c;实现第一个项目的量产。」速腾聚创CEO邱纯潮在发布会现场…

Python连接Oracle数据库问题解决及Linux服务器操作知识

背景说明 最近在做一个视频分析的项目&#xff0c;然后需要将视频分析的数据写入到oracle数据库&#xff0c;直接在服务器上测试数据库连接的时候出现了这个bug提示&#xff0c;自己通过不断的研究探讨&#xff0c;最终把这个问题成功进行了解决&#xff0c;在这里进行一下记录…

Avi Wigderson:理论计算机科学的巨人

&#x1f3c6;个人专栏 &#x1f93a; leetcode &#x1f9d7; Leetcode Prime &#x1f3c7; Golang20天教程 &#x1f6b4;‍♂️ Java问题收集园地 &#x1f40d; Python工具 &#x1f334; 成长感悟 欢迎大家观看&#xff0c;不执着于追求顶峰&#xff0c;只享受探索过程 A…

LeetCode-热题100:98. 验证二叉搜索树

题目描述 给你一个二叉树的根节点 root &#xff0c;判断其是否是一个有效的二叉搜索树。 有效 二叉搜索树定义如下&#xff1a; 节点的左子树只包含 小于 当前节点的数。节点的右子树只包含 大于 当前节点的数。所有左子树和右子树自身必须也是二叉搜索树。 示例 1&#x…