python - Pandas基础

article/2025/10/9 9:07:40

pandas

简介

  • 基于numpy的工具

  • 高效提供了大量库和一些标准的数据模型

    相当于Numpy的一维数组,但是与普通的一维数组不同,Series支持对数据的自定义标签也就是index(索引),通过索引可以访问Series的元素

Series

索引

简单的创建

import pandas as pd
sel = pd.series()
print(sel)

我们发现当我们没有创建索引的时候回自动创建一个类似于下标的索引,从0开始,

索引的设置

使用data设置值,index设置索引

import pandas as pd 
sel = pd.Series(data=[5,4,3,2],index=[1,2,3,4])
print(sel)

通过数组对象的index属性可以直接获取索引

value 可以获取值

import pandas as pd
sel = pd.Series(data=[1,2,3,4,5],index=list('abcde'))
print(sel.values) # 获取值
print(sel.index) # 获取索引
print(list(sel.iteritems())) # 获取索引与值的键值对列表

[1 2 3 4 5]
Index([‘a’, ‘b’, ‘c’, ‘d’, ‘e’], dtype=‘object’)
[(‘a’, 1), (‘b’, 2), (‘c’, 3), (‘d’, 4), (‘e’, 5)]

字典转Series

import pandas as pd
pd_dict = {"red":20,"blue":40,"green":40}
sel = pd.Series(pd_dict)
print(sel)

red 20
blue 40
green 40
dtype: int64

通过 索引|位置 得到值

通过 数组[索引] 可以获取值

import pandas as pd
sel = pd.Series({"red":20,"blue":40,"green":40})
print(sel["red"])

20

位置也可以获取值,位置实际就是从0开始的数组下标索引

通过索引|位置列表组可以获取数组的多个值

import pandas as pd
sel = pd.Series({"red":20,"blue":40,"green":40})
print(sel[['red','blue']])

red 20
blue 40
dtype: int64

修改index值

  • 使用index修改数组本身索引
import pandas as pd 
sel = pd,Series({"red":20,"blue":40,"green":40})
sel.index=['r','g','b']
  • 使用reindex修改数组索引获取新数组
import pandas as pd
sel = pd.Series({"red":20,"blue":40,"green":40})
ret = sel.reindex(['r','g','b'])

如果index超出了值的长度,那么默认补全NaN给超出的部分

drop 删除值

使用drop删除指定索引的数据,传入列表就是删除多个

import pandas as pd
sel = pd.Series({"red":20,"blue":40,"green":40})
ret = sel.drop(["red","green"]) # 删除索引red与green

一维数组的计算

Series支持numpy的计算,且Series的计算与index进行对应即映射,相同的index进行运算,如果运算的一方无法与另一方对应那么运算的结果该index的值就是NaN

import pandas as pd
selA = pd.Series({"banana":12,"apple":41,"orange":100})
selB = pd.Series({"banana":42,"apple":11,"gruy":100})
selC = selB + selA
print(selC)

apple 52.0
banana 54.0
gruy NaN
orange NaN
dtype: float64

DataFrame

DataFrame是一个pandas的二维数组 所以他有两个索引一个是行索引一个是列索引

基础使用

创建DataFrame(DF)

import pandas as pd
import numpy as np
DF_A = pd.DataFrame(np.random.randint(0,10,(4,4)))
# 将四行四列的随机numpy数组转化成DF

​ 0 1 2 3
0 8 2 2 3
1 9 4 8 4
2 4 4 2 5
3 3 9 5 8

修改两个索引的方法

import pandas as pd
import numpy as npdf = pd.DataFrame(np.random.randint(0,100,(4,4)))
# 也可以使用index参数与columns参数修改df.index = [1,2,3,4] # 行索引
df.columns = list("ABCD") # 列索引print(df)

字典转DF

通过字典生成的DF,字典的键会自动成为列索引,其值会成为该列的数组元素

import pandas as pd
dict_pd = {"banana":[10,12,9],"orange":[99,121,160]}
df = pd.DataFrame(dict_pd,index=["超市A","超市B","超市C"])
print(df)
​			banana  orange
超市A      10       99
超市B      12       121
超市C       9        160

当然我们可以值为Series的字典来创建数组

常用属性方法

import pandas as pddata = pd.DataFrame({"banana": [10, 12, 9], "orange": [99, 121, 160]},index=["超市A", "超市B", "超市C"]
) 
index = data.index.tolist()  # 将DF的index收集成列表
columns = data.columns.tolist()  # 将DF的列索引收集成列表
shape = data.shape  # 获取数组而定行与列
print(data.shape)  # DF 的维度
print(shape)
print(data.values)  # DF数据查看
print(data.info)  # 数据的信息
print(data.head(2))  # 查看前2行,默认是前五行
print(data.tail())  # 显示后几行
  • rename()
    • 可以修改DF的 index 与 colunms的值
def rename_index(x):return str(x + 1)def rename_columns(x):return x.replace("User", "")
a = df.rename(index=rename_index, columns=rename_columns)
print(a)

​ A B
1 1 2
2 2 3
3 4 5
4 5 6
5 6 1

使用键值对来修改单一的index 与 columns 也是可以的

  • set_index
    • 将指定列的值赋值给index
b = df.set_index("UserA",drop=False)
print(b)

定位

获取指定列

import pandas as pd
data = pd.DataFrame({"banana": [10, 12, 9], "orange": [99, 121, 160]},index=["超市A", "超市B", "超市C"]
)
col_banana = data["banana"]
# 获取指定的列 返回值DF
print(data[["banana","orange"]])
# 获取多列返回值DF
print(df.loc[:,["UserA"]]) # 获取UserA列
ret = data[0:1]
# 获取一行

指定行

使用loc定位行

import pandas as pd
df = pd.DataFrame({"UserA":[1,2,4,5,6],"UserB":[2,3,5,6,1]})
data_userA_col = df["UserA"].loc[1:4] # 获取UserA列的 1—4index 的值print(data_userA_col)

添加列与行

运算方法

import pandas as pd
df = pd.DataFrame({"UserA": [1, 2, 4, 5, 6], "UserB": [2, 3, 5, 6, 1]})# 以后数据源就是这个了# 追加
df["UserC"] = [4,2,3,4,5] # 长度需要与row相同# 指定插入
list_col = df.columns.tolist() # 将列转为列表
list_col.insert(2,"UserD") # 向列表插入数据
e = df.reindex(columns=list_col) # 修改数组的列 reindex 可以对原行列索引重新构建索引值
e["UserD"] = [4,1,5,4,1]
print(e)# 指定插入II
f = df
f.insert(2,"userD",[24,5,1,2,4])
print(f)

append

  • 将两个DF合并成一个DF
dataA = pd.DataFrame({"name":["刘博源"],"Tel":[1271124111]})
dataB = pd.DataFrame({"name":["李三"],"Tel":[1212341111]})
data_sum = dataB.append(dataA,ignore_index=True)
print(data_sum)
# ignore_index:是否忽略index,如果是True值,那么添加的时候就忽略添加数据的index值,而是递增之前的index如果是ignore_index=False 那么就会保留之前的index(视频有个错误,,)f

行列合并

ret = pd.concat([df1,df2],axis=1) # 按行拼接 X + X 
'''
{——}{——}
'''
ret2 = pd.concat([df1,df2],axis=0) # 安列拼接
'''
{--}
{--}
'''

数据处理

滤除缺失值

  • dropna()
import pandas as pd
import numpy as np#Series
df = pd.Series([np.nan,12,np.nan])
print(df)
df_noNan = df.dropna()
df_notNan = df.notnull() # 广播是否为Nan#Pandas
df1 = pd.DataFrame([[1,2,4],[4,1,np.nan],[np.nan,13,1]])
df_clear = df1.dropna()
‘’‘
dropna params:axis默认 : 过滤行axis = 1:过滤列how判断方式 为 any 时 就是遇见Nan就删除整行|列判断方式 为 all 时 就是全部Nan就删除整行|列thresh保留 至少hresh个非nan的 行|列
’‘’
print(df_clear) # 过滤所有包含Nan值的行

填充空值

  • fillna()
df1.fillna(1) #  将所有为Nan的Value替换成1
'''
inplace:是否在原数组修改不返回值,默认False
'''df1 = pd.DataFrame([[1,2,4],[4,1,np.nan],[np.nan,13,1]],columns=[1,2,3],index=list("abc"))
df1.fillna({1:3,2:4,3:4})
# 根据columns进行字典的填充# 指定列(位置)填充
df1.fillna([:,1].fillna(5,inplace=True))# 前后值填充
ret = df.fillna(method="bfill") # 使用后面(下一行同列)的值填充
ret = df.fillna(method="ffill") # 使用前面(上一行同列)的值填充
'''
params:limit:限制的填充的行数axis:改变填充的方向 1:同行不同列的填充0:同列不同行的填充'''

去重

df = pd.DataFrame({"A":[1,2,1,5,6,1],"B":[1,2,1,5,1,2]})
print(df)isRepeat = df.duplicated() # 判断是否重复(行与行之间的)
print(isRepeat)dropedRepeat = df.drop_duplicates() # 删除重复行 
print(dropedRepeat)
# 可以传入一个列表参数给drop_duplicates代表指定的列的重复判断
'''
params:inplace:修改原数组不返回新数组
'''

数据合并

join()

df3 = pd.DataFrame({"Red": [1, 4, 5], "Blue": [2, 4, 5], "Yellow": [1, 5, 6]},index=list("123"))
df4 = pd.DataFrame({"Gury": [1, 4, 5], "Green": [2, 4, 5], "Purple": [1, 5, 6]},index=list("124"))
print(df3.join(df4))
'''将 df3 与 df4 进行横向的合并 index会默认以df3 join的调用者为基础 参数df4多余的idnex在合并时被忽略没有的index合并值为填充为NaNparams:how:如何合并-left 左合并默认的合并法则- right 右合并index会以 df4 参数为基础进行合并 - outer 全合并index 会将进行合并的两个数组全部的索引为基础进行合并
'''

merge()

pd_char = pd.DataFrame(data=[[1001,"向老表","A"],[1002,"刘天皇","B"],[1003,"佘东阳","C"],[1004,"岳顺江","C"]],columns=["编号","名称","工程编号"])
pd_project = pd.DataFrame(data=[["A","数据处理集群管理"],["B","全栈开发"],["C","前端开发&数据可视化"]],columns=["工程编号","名称"])pd_sum = pd.merge(pd_char,pd_project,on="工程编号",suffixes=['_人物','_工程'],how="inner") # on 相当于链接的键值
'''
how:inner :内连接left:左连接right:有链接outer:外连接
suffixes:如果链接的两个DF有相同的Columns那么我们就可以给这两个DF的同名索引取后缀,suffixes可以规定两个后缀
'''
print(pd_sum)
​	编号   		名称_人物 		工程编号        名称_工程
0  1001  		向老表    		A    				数据处理集群管理
1  1002  		刘天皇    		B        			全栈开发
2  1003  		佘东阳   		 C  	  			前端开发&数据可视化
3  1004  		岳顺江   		 C 	   			前端开发&数据可视化

多层索引

我们可能会遇见这种索引

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-iCorbOOS-1618501305960)(Pandas.assets/image-20210414023130871.png)]

也就是一个大索引可以分为多个小索引(层级索引),多个小索引又有多个具体的值

如何具体去创建这样的数组 我们可以通过以下的代码

Series多层索引数组

import numpy as np
import pandas as pd
Mark_Numpy = np.random.randint(40,100,size=(6,))
Mark_Sum_version_1 = pd.Series(Mark_Numpy,index=['a','a','b','b','c','c']) # 简单的创建
Mark_Sum_version_2 = pd.Series(Mark_Numpy,index=[['a','a','b','b','c','c'],["语文","数学","语文","数学","语文","数学"]]) # 多层索引 创建
print(Mark_Sum_version_2)
print(Mark_Sum_version_2["a","数学"])# 值的定位,注意区分取多值与这个的差别
'''
补充
使用iloc定位的时候因为使用的是位置
索引传入的小标还是最内层的索引 
'''

a 语文 60
数学 64
b 语文 49
数学 94
c 语文 79
数学 51
dtype: int32

DataFrame多层索引数组

这里讨论的多索引是index方面的而不是columns方面的

# 方法一
multilayerDF = pd.DataFrame(data=numpy_array,columns=["入学成绩","月考成绩","期末成绩"],index=[['刘博源','刘博源','刘博源',"向国骑","向国骑","向国骑"],["java",'python','English',"java",'python','English']]
)
print(multilayerDF)# 方法二
outterIndex = ["刘博源", "刘博源", "刘博源", "向国骑", "向国骑", "向国骑"]  # 外层索引
innerIndex = ["java", 'python', 'English', "java", 'python', 'English']  # 内层索引mi = pd.MultiIndex.from_arrays([outterIndex, innerIndex])  # 创建索引
df2 = pd.DataFrame(data=np.random.randint(10, 40, (6, 3)), index=[outterIndex, innerIndex])
print(df2)# 方法三 可以不用格式数组里面究竟有多少个重复的元素
outterIndex = ["刘博源",'向国骑']
innerIndex = ["Python","Java","English"]mi = pd.MultiIndex.from_product([outterIndex,innerIndex]) # 创建索引
Mpd = pd.DataFrame(np.random.randint(1,100,(6,3)),index=mi)
print(Mpd)
# 利用这种方式创建一个Series试试?
        ​				入学成绩   月考成绩  期末成绩刘博源  	java       	67    82    82python     92    67    97English    87    72    85向国骑 	java       81    75    68python     80    53    94English    84    65    75

多索引数组的取值

# S是一个多层索引Series D是一个多层索引DataFrameprint(S['a']) # 外层索引为a
print(S[['a','b']]) # 外层索引为a,b(多外层获取)
print(S["a","期末"]) # 取a索引的期末子索引print(D.loc["a"])# 外层索引为a
print(D[['a','b']])# 外层索引为a,b(多外层获取)
print(D["a","期末"])# 取a索引的期末子索引

时间序列

时间序列可以用来处理表示时间的数据

使用date_range()生成有序的时序
单位:D   日历上的每一天B   工作日的每天H   每小时T|min   每分钟S   每秒L|ms    每毫秒M   日历日的月底日期BM  工作日的月底日期MS  日历日的月初日期BMS 工作日的月初日期
freq:日期偏移量时间的间隔是一个字符串,格式为:数字+单位比如:10D 代表间隔十天
periods:固定时期取值为整数或者Nonestart, end, periods, freq 不能同时存在
# 创建含有时序的DF
data = pd.date_range(start='20190101', end='20200101')  # 创建时序time_dataFrame = pd.DataFrame(data=np.random.randint(80,700,(data.size,3)),index=data, # 通过时序创建index索引columns=["早上","中午","晚上"]
)# 时序df的检索
year_2019_date = time_dataFrame['2019']  # 获取2019年的数据
year_2019_month_5_date = time_dataFrame['2019-05']  # 获取2019年5月份的数据
year_2019_during_5mTo8m = time_dataFrame.loc['2019-05-01':'2019-08-01']  # 获取五月到8月的数据
'''
这里可以不使用loc:
year_2019_during_5mTo8m = time_dataFrame['2019-05-01':'2019-08-01']  # 获取五月
但是这样会报警告
'''print(year_2019_during_5mTo8m)date = pd.date_range(start="2021-04-15",periods=40,freq='2h')
df = pd.DataFrame(np.random.randint(1,40,(date.size,3)),index=date)during_1pTo5p = df.between_time("1:00","5:00")
print(during_1pTo5p)
# 获取每天在1点到五点的数据

分组聚合

分组

df = pd.DataFrame(columns=["姓名", "订单编号", "金额"],data=[["刘博源", 1, 1020], ["李四", 2, 1000], ["李四", 3, 1050], ["刘博源", 4, 1920], ["向国骑", 5, 1100]])
groupbyName_df = df.groupby("姓名")  # 通过姓名分组
AllGroupsbyName = groupbyName_df.groups  # 通过分组操作分出来的组(键值对出现 键是分组依据 值是对应的索引序列)
print(AllGroupsbyName)count_group_name_df = groupbyName_df.count()  # 查看分组的分组数与其对应值的数量
for name,Group in groupbyName_df:  # 使用遍历可以对分组结果进行对象解析print(name)  # 依次分组的数组名称print(Group)  # 以关键字分组的数组小组Path_df_LiSi = groupbyName_df.get_group("李四")  # 获取按名称分组的李四组groupNameOnlySeeOrderColumns = df["订单编号"].groupby(df["姓名"])
# 如果只看DF的某列对全DF分组
print(groupNameOnlySeeOrderColumns.get_group("向国骑"))
groupNameAndJinE_df = df.groupby(["姓名",'金额'])

聚合

# 可以对分组后的对象进行聚合函数运算# 题:通过下列数组求出每个人的总和
df_mark = pd.DataFrame([["刘博源","英语",100],["向国骑","英语",90],["刘博源","python",82],["向国骑","Java",75]],columns=["考生","科目","成绩"])
df_mark_groupByName = df_mark.groupby("考生")
df_mark_avg = df_mark_groupByName.sum()
# 在进行运算的时候不是数值的列 会被清除 但是会保留分组依据列索引 
print(df_mark_avg)df_mark2 = pd.DataFrame([[1001,"刘博源", "英语", random.randint(1, 100)], [2001,"向国骑", "英语", random.randint(1, 100)],[1002,"刘博源", "python", random.randint(1, 100)], [2002,"向国骑", "Java", random.randint(1, 100)]],columns=["考号","考生", "科目", "成绩"])df_onlyOperaMark = df_mark2["成绩"].groupby(df_mark2["考生"]) # 只计算成绩列 不去计算考号列
print(df_onlyOperaMark.sum())df_onlyOperaMark = df_mark2.groupby("考生")["成绩"].sum() # 另一种写法
print(df_onlyOperaMark)

其他的聚合函数

聚合函数作用
min()最小值
max()最大值
sum()求和
mean()平均数
std()标准差
size()按照groupby的值计算该值的个数 与count函数的区别在于,size函数会计算NAN值,而count函数不会计算NAN值
nunique()去掉重复值后进行计数
count()计算个数

agg自定义聚合函数

使用agg可以使用聚合函数

df_grouper.agg("sum") # df.sum()
df_grouper.agg("count") # df.agg()
df_grouper.agg("sum","count") # 多聚合
def peak_range(df):return df.max() - df.agg('min')
df_grouper.agg(peak_range)

apply

用处一:可以通过自定义函数来筛选数据

def isSixStar(value):return True if value == 6 else Falsedf_data = pd.DataFrame([["能天使", "狙击", 6, 241], ["克洛斯", "狙击", 3, 41], ["莫斯提马", "术士", 6, 511], ["月见夜", "近卫", 3, 51], ["安洁莉娜", "辅助", 6, 102]],columns=["名称", "类型", "星级", "攻击"])
# df_group_job = df_data.groupby("类型")
is_six_star = df_data["星级"].apply(isSixStar)  # 判断是否为6星人物
print(is_six_star)
df_data["是否为六星"] = is_six_star
print(df_data)
def sort_gat_fristAndSecond(df, columns, wight):'''通过列排序_从小到大:param df: 参与排序的数组:param columns:指定列:param wight: 前几位:return: 数组更具排序前几位列'''sort_df = df.sort_values(by=columns)print(sort_df)df_temp.groupby("星级").apply(sort_gat_fristAndSecond, columns="攻击", wight=2)

在这里插入图片描述


http://chatgpt.dhexx.cn/article/MH9lbLet.shtml

相关文章

【阿里内部教程】python初阶:基础语法 python全栈自动化测试系类

目录 很多小伙伴可能都没有看过凡哥的视频,所以大家可能对凡哥不是很了解这里先和大家来个自我介绍 凡哥我已经有着十二年互联网自动化测试和测试开发工程师,拥有丰富的自动化测试平台及测试开发经验,擅长接口测试、Python自动化全栈&#x…

opencv python 常用方法

点击:OpenCV--Python 基本使用 一、基本方法 1、cv2.imread() 读入图像;第一个参数为图像路径;第二个为cv2.IMREAD_COLOR:读入彩色图像;cv2.IMREAD_GRAYSCALE:读入灰度图像。 import cv2 import matplotlib.pyplot …

iOS开发通过微信学习WCDB(四)

最近打算将封装一个基于wcdb操作的数据库私有库,在封装使用的过程中遇到了一些问题,将问题整理了一下,分享给大家。 私有pod库依赖于WCDB 造成lint失败 最开始遇到这个问题的时没有眉目,后来看到打包方式都是静态库,后…

微信移动端数据库组件WCDB系列(二) — 数据库修复三板斧

前言 长久以来SQLite DB都有损坏问题,从Android、iOS等移动系统,到Windows、Linux 等桌面系统都会出现。由于微信所有消息都保存在DB,服务端不保留备份,一旦损坏将导致用户消息被清空,显然不能接受。 我们即将开源的移…

微信 WCDB for Android的接入

接入 WCDB Android 项目接入 WCDB,可以选择通过 Maven 接入或通过 AAR 包接入。 通过 Maven 接入 对于大部分开发者,推荐使用 Maven 接入 WCDB,在 APP 模块的 build.gradle 下添加 WCDB 依赖即可 dependencies {// 修改"1.0.0"…

关于WCDB Swift 的一些简易使用

wcdb 开源地址:https://github.com/Tencent/wcdb 一、wcdb介绍 引用官方说法:“WCDB Swift 是一个易用、高效、完整的移动数据库框架,它基于 SQLite 和 SQLCipher 开发。” 鹅厂出品的值得信赖。于是就打算在新的项目中使用它。 三大特性…

微信 WCDB 正式开源——高效易用的移动数据库框架

前沿介绍 腾讯开源微信数据库框架WCDB,他是一个高效、完整、易用的移动数据库框架,基于SQLCipher,支持iOS, macOS和Android。 便捷地定义表、索引、约束,并进行增删改查操作 项目演示效果如下: 微信 即时通讯软件 微信&#x…

Wcdb android 目录,WCDB漫谈

前言 移动端的数据库选型一直是一个难题,直到前段时间看到了WeMobileDev(微信前端团队)放出了第三个开源组件-WCDB WCDB(WeChat DataBase)是微信官方的移动端数据库组件,致力于提供一个高效、易用、完整的移动端存储方案 微信团队怎么说 基于SQLCipher W…

iOS开发-关于微信WCDB的使用 WCDB嵌套模型的使用

iOS开发-关于微信WCDB的使用 WCDB嵌套模型的使用 前言开发前准备开发关于生成WCDB文件 选择new file即可找到关于嵌套模型的生成 分两步 选择new file即可找到增删改查的封装使用 总结 前言 iOS开发中有需要数据库的存储,表的增删改查等,FMDB和最近流行…

iOS开发通过微信学习WCDB(三)

通过之前的两篇文章对wcdb能够简单的使用了,这些知识储备多时,最近终于可以派上用场了,最近app有一个通讯录的新功能,实现联系人列表的排序,以及检索,刚好可以用用wcdb去实现。 联系人模型的建立 我首先建…

WCDB使用笔记

本地数据加密 由于项目涉及到一些用户隐私数据的存储,所以需要对保存在客户端本地的数据进行加密,以防止用户隐私数据在设备被root的情况下出现泄漏。目前android的本地数据存储基本分为file,sharepreference和database,所以对数…

iOS开发通过微信学习WCDB(一)

最近通过对微信ipa包解压发现微信有使用WCDB这个开源库,搜索了一下了解到WCDB(WeChat Database)是一个高效、完整、易用的移动数据库框架,基于SQLCipher,支持iOS, macOS和Android。经过分析对比,个人感觉WC…

微信移动端数据库组件 WCDB 系列(三) — 解析 WINQ 原理

背景 高效、完整、易用是 WCDB 的基本原则。前几篇文章分享了 WCDB 的基本用法和修复工具,接下来将更深入地聊聊 WCDB 在易用性上的思考和实践。 对于各类客户端数据库,似乎都绕不开拼接字符串这一步。即便在 Realm 这样的 NoSQL 的数据库中&#xff0…

WCDB源码解析

源文链接:http://xiangwangfeng.com/2018/01/08/WCDB-源码解析 起因 最近开了个新项目,项目的主程童鞋引入了 WCDB 代替原先自制的 KeyValueStore 和 FMDB。问为何,答曰:好用,线程安全又高效。又问具体实现细节&#x…

IOS数据存储 之WCDB (二)WCDB.swift使用篇

IOS数据存储 之WCDB (二)WCDB.swift使用篇 1.WCDB.Swfit基础使用1.1 WCDB.Swfit 简介1.1.1 模型绑定1.1.2 创建数据库与表1.1.3 操作数据1.1.3.1 插入操作1.1.3.2 查找操作1.1.3.3 更新操作1.1.3.4 删除操作 1.2. 模型绑定1.2.1 Swift 模型绑定1.2.2 字段…

Android使用WCDB+Room 总结

最近项目有需要用到wcdb数据库,并且保证和IOS互通数据,在网上找很多相关资料,最后还是靠自己一点点摸索成功,现在做个总结。 一、在gradle 里加上 WCDB 相关的 room 组件 def room_version "2.3.0"// wcdb数据库和roo…

IOS数据存储 之WCDB (一)

IOS数据存储 之WCDB (一) 1. WCDB 简介1.1 使用WCDB框架3大优势1.2 WCDB 的一些基础概念1.2.1 类字段绑定(ORM)1.2.2 WINQ(WCDB语言集成查询)1.2.2.1 字段映射与运算符1.2.2.2 字段组合1.2.2.3 AllProperti…

iOS开发 数据存储之WCDB的介绍

一.介绍 WCDB是一个高效、完整、易用的移动数据库框架,基于SQLCipher,支持iOS,macOS和Android 二.基本特性 易用,WCDB支持一句代码即可将数据取出并组合为object WINQ(WCDB语言集成查询):通过WINQ,开发者无须为了拼接SQL的字符串而写一大坨胶水代码ORM(Object Relational Ma…

开源微信小程序自助建站系统源码 含精美的多行业模板和搭建教程

分享一个微信小程序自助建站系统源码,含各行各业的小程序模板和搭建教程,可一键切换模板,自由DIY,搭建属于你自己的小程序。 特色功能一览: 11、支持创建多个小程序!(没有数量限制,后…

强大易用的开源建站工具Halo

最近无意间看到别人的博客外观非常美观,便萌生了偷师学艺的想法…所以就看到看了Halo这个开源的建站项目,其实使用起来非常简单,但是想要做一个类似的开源建站工具,谈何容易 访问官网 https://halo.run/ 使用docker部署 搜索镜像halo do…