pandas中的分组技术

目录

  • 1  分组操作

    • 1.1  按照列进行分组
    • 1.2  按照字典进行分组
    • 1.3  根据函数进行分组
    • 1.4  按照list组合
    • 1.5  按照索引级别进行分组
  • 2  分组运算
    • 2.1  agg
    • 2.2  transform
    • 2.3  apply
  • 3  利用groupby技术多进程处理DataFrame

我们在这里要讲一个很常用的技术, 就是所谓的分组技术, 这个在数据库中是非常常用的, 要去求某些分组的统计量, 那么我们需要知道在pandas里面, 这些分组技术是怎么实现的.

分组操作

我们这里要来聊聊在pandas中实现分组运算, 大致上可以按照列, 字典或者Series, 函数, 索引级别进行分组, 我们会逐渐来介绍.

按照列进行分组

import pandas as pd
from pandas import DataFrame, Series
import numpy as np

sep = "---------------------------------------------------------------------------"
data = DataFrame({"key1": [‘a‘, ‘a‘, ‘b‘, ‘b‘, ‘a‘], "key2": [‘one‘, ‘two‘, ‘one‘, ‘two‘, ‘one‘], ‘data1‘: np.random.randn(5), ‘data2‘: np.random.randn(5)})
print(data)
      data1     data2 key1 key2
0  0.733951  0.000379    a  one
1  1.039029  0.852930    a  two
2  0.921413 -1.644942    b  one
3  0.294560  0.521525    b  two
4  0.286072 -0.074574    a  one

data1按照key1分组为:

groups = data[‘data1‘].groupby(data[‘key1‘])

我们发现得到了一个SeriesGroupBy 对象, 现在我们对这个对象进行迭代:

for name, group in groups:
    print(name)
    print(sep)
    print(group)
    print(sep)
a
---------------------------------------------------------------------------
0    0.733951
1    1.039029
4    0.286072
Name: data1, dtype: float64
---------------------------------------------------------------------------
b
---------------------------------------------------------------------------
2    0.921413
3    0.294560
Name: data1, dtype: float64
---------------------------------------------------------------------------

我们发现, groups有(key, Series)对组成, key根据什么来分组的元素, Series(DataFrame)是分组的元素, Series(DataFrame)的name还是原来的列名.

对你分组进行迭代, 用:

for name, group in groups

groups = data.groupby(data[‘key1‘])
for name, group in groups:
    print(name)
    print(sep)
    print(group)
    print(sep)
a
---------------------------------------------------------------------------
      data1     data2 key1 key2
0  0.733951  0.000379    a  one
1  1.039029  0.852930    a  two
4  0.286072 -0.074574    a  one
---------------------------------------------------------------------------
b
---------------------------------------------------------------------------
      data1     data2 key1 key2
2  0.921413 -1.644942    b  one
3  0.294560  0.521525    b  two
---------------------------------------------------------------------------

groupby就是按照某个值来分组, 无论是对series还是dataframe, 都成立.

我们可以在分好组的对象上调用统计函数.

data.groupby(data[‘key1‘]).mean()

.dataframe thead tr:only-child th { text-align: right }
.dataframe thead th { text-align: left }
.dataframe tbody tr th { vertical-align: top }

data1 data2
key1
a 0.686351 0.259578
b 0.607986 -0.561709

在每个分组上分别对每个每一列求均值, 如果是非数字列, 或默认剔除.

作业1:在每个分组上分别对每个每一行求均值.

提示: data.groupby(data[‘key1‘]).mean(axis=1)是行不通的.

对于多个列进行分组, 分组的key是对应分组元素的元组.

作业2:对DataFrame用多个列进行分组.

下面其我们来看一个语法糖:

data.groupby([data[‘key1‘], data[‘key2‘]])
<pandas.core.groupby.DataFrameGroupBy object at 0x000001D080230278>

它等价于:

data.groupby([‘key1‘, ‘key2‘])
<pandas.core.groupby.DataFrameGroupBy object at 0x000001D080230630>

我们来验证一下:

groups =data.groupby([data[‘key1‘], data[‘key2‘]])
for name, group in groups:
    print(name)
    print(sep)
    print(group)
    print(sep)
(‘a‘, ‘one‘)
---------------------------------------------------------------------------
      data1     data2 key1 key2
0  0.733951  0.000379    a  one
4  0.286072 -0.074574    a  one
---------------------------------------------------------------------------
(‘a‘, ‘two‘)
---------------------------------------------------------------------------
      data1    data2 key1 key2
1  1.039029  0.85293    a  two
---------------------------------------------------------------------------
(‘b‘, ‘one‘)
---------------------------------------------------------------------------
      data1     data2 key1 key2
2  0.921413 -1.644942    b  one
---------------------------------------------------------------------------
(‘b‘, ‘two‘)
---------------------------------------------------------------------------
     data1     data2 key1 key2
3  0.29456  0.521525    b  two
---------------------------------------------------------------------------
groups = data.groupby([‘key1‘, ‘key2‘])
for name, group in groups:
    print(name)
    print(sep)
    print(group)
    print(sep)
(‘a‘, ‘one‘)
---------------------------------------------------------------------------
      data1     data2 key1 key2
0  0.733951  0.000379    a  one
4  0.286072 -0.074574    a  one
---------------------------------------------------------------------------
(‘a‘, ‘two‘)
---------------------------------------------------------------------------
      data1    data2 key1 key2
1  1.039029  0.85293    a  two
---------------------------------------------------------------------------
(‘b‘, ‘one‘)
---------------------------------------------------------------------------
      data1     data2 key1 key2
2  0.921413 -1.644942    b  one
---------------------------------------------------------------------------
(‘b‘, ‘two‘)
---------------------------------------------------------------------------
     data1     data2 key1 key2
3  0.29456  0.521525    b  two
---------------------------------------------------------------------------

我们发现输出结果是一模一样, 总结一下:

data.groupby([data[‘key1‘], data[‘key2‘]])等价于data.groupby([‘key1‘, ‘key2‘])

进一步:

data[‘data1‘].groupby([data[‘key1‘], data[‘key2‘]])等价于data.groupby([‘key1‘, ‘key2‘])[‘data1‘]

作业3: 验证data[‘data1‘].groupby([data[‘key1‘], data[‘key2‘]])等价于data.groupby([‘key1‘, ‘key2‘])[‘data1‘].

data.groupby([‘key1‘, ‘key2‘])[‘data1‘]
<pandas.core.groupby.SeriesGroupBy object at 0x000001D0FCD95D68>
data.groupby([‘key1‘, ‘key2‘])[[‘data1‘]]
<pandas.core.groupby.DataFrameGroupBy object at 0x000001D080232898>

我不知道大家发现没有, 这两个返回的数据类型是有区别的, 我们仔细来看看:

data[[‘data1‘]] # 这是一个DataFrame

.dataframe thead tr:only-child th { text-align: right }
.dataframe thead th { text-align: left }
.dataframe tbody tr th { vertical-align: top }

data1
0 0.733951
1 1.039029
2 0.921413
3 0.294560
4 0.286072
data[‘data1‘] # 这是一个Series
0    0.733951
1    1.039029
2    0.921413
3    0.294560
4    0.286072
Name: data1, dtype: float64

那么这里的区别就不言而喻了吧

groups = data.groupby([‘key1‘, ‘key2‘])[[‘data1‘]]

for name, group in groups:
    print(name)
    print(sep)
    print(group)
    print(sep)
(‘a‘, ‘one‘)
---------------------------------------------------------------------------
<class ‘pandas.core.frame.DataFrame‘>
---------------------------------------------------------------------------
(‘a‘, ‘two‘)
---------------------------------------------------------------------------
<class ‘pandas.core.frame.DataFrame‘>
---------------------------------------------------------------------------
(‘b‘, ‘one‘)
---------------------------------------------------------------------------
<class ‘pandas.core.frame.DataFrame‘>
---------------------------------------------------------------------------
(‘b‘, ‘two‘)
---------------------------------------------------------------------------
<class ‘pandas.core.frame.DataFrame‘>
---------------------------------------------------------------------------

结果是一样的.

data.groupby([‘key1‘, ‘key2‘])[[‘data1‘]].mean()

.dataframe thead tr:only-child th { text-align: right }
.dataframe thead th { text-align: left }
.dataframe tbody tr th { vertical-align: top }

data1
key1 key2
a one 0.510012
two 1.039029
b one 0.921413
two 0.294560
data.groupby([‘key1‘, ‘key2‘])[‘data1‘].mean()
key1  key2
a     one     0.510012
      two     1.039029
b     one     0.921413
      two     0.294560
Name: data1, dtype: float64

在做数据聚合的时候就发现了不同,

[[‘data1‘]]得到的是一个DataFrame, 而[‘data1‘]得到的是Series.

按照字典进行分组

我们来看一个按照字典进行分组的例子:

data = DataFrame(np.random.randn(5, 5), columns=[‘a‘, ‘b‘, ‘c‘, ‘d‘, ‘e‘], index=[‘joe‘, ‘steve‘, ‘wes‘, ‘jim‘, ‘Travis‘])
data

.dataframe thead tr:only-child th { text-align: right }
.dataframe thead th { text-align: left }
.dataframe tbody tr th { vertical-align: top }

a b c d e
joe -0.089597 1.239307 2.173063 -0.519295 -1.783812
steve 0.539109 0.724553 -0.041899 0.787494 0.394633
wes -0.055417 0.384068 -0.594006 -0.451587 0.722761
jim -0.056767 0.398863 2.140669 -1.060791 -0.953756
Travis 0.245142 -0.468819 -0.863372 -0.151966 1.185567
# 定义一个分组的字典, a, b, c --> red, d, e --> blue
mapping = {‘a‘:‘red‘, ‘b‘:‘red‘, ‘c‘: ‘red‘, ‘d‘:‘blue‘, ‘e‘: ‘blue‘}
data.groupby(mapping, axis=1).mean()   # 对每一个分组求平均

.dataframe thead tr:only-child th { text-align: right }
.dataframe thead th { text-align: left }
.dataframe tbody tr th { vertical-align: top }

blue red
joe -1.151554 1.107591
steve 0.591063 0.407255
wes 0.135587 -0.088452
jim -1.007273 0.827589
Travis 0.516800 -0.362350

作业4:自己设计一个index的mapping, 按axis=0进行分组.

根据函数进行分组

话不多说, 直接来看例子:

data.groupby(len).mean()

.dataframe thead tr:only-child th { text-align: right }
.dataframe thead th { text-align: left }
.dataframe tbody tr th { vertical-align: top }

a b c d e
3 -0.067260 0.674079 1.239909 -0.677224 -0.671602
5 0.539109 0.724553 -0.041899 0.787494 0.394633
6 0.245142 -0.468819 -0.863372 -0.151966 1.185567

我们发现, 字典和函数都是作用到索引上的.

按照list组合

这个例子非常简单:

data.groupby([‘1‘, ‘1‘, ‘1‘, ‘2‘, ‘2‘]).mean()

.dataframe thead tr:only-child th { text-align: right }
.dataframe thead th { text-align: left }
.dataframe tbody tr th { vertical-align: top }

a b c d e
1 0.131365 0.782643 0.512386 -0.061130 -0.222139
2 0.094188 -0.034978 0.638649 -0.606378 0.115905

他会自动判断是按照列还是list.

按照索引级别进行分组

作业5: 自己学习按索引级别进行分组.

分组运算

分组运算主要设计到3个函数, agg, transform和apply.

我们一个一个来看.

agg

data = DataFrame({"key1": [‘a‘, ‘a‘, ‘b‘, ‘b‘, ‘a‘], "key2": [‘one‘, ‘two‘, ‘one‘, ‘two‘, ‘one‘], ‘data1‘: np.random.randn(5), ‘data2‘: np.random.randn(5)})
data

.dataframe thead tr:only-child th { text-align: right }
.dataframe thead th { text-align: left }
.dataframe tbody tr th { vertical-align: top }

data1 data2 key1 key2
0 0.441278 -0.848457 a one
1 1.843375 -0.522482 a two
2 -1.435176 -0.191682 b one
3 -2.700772 -0.832993 b two
4 -1.430386 -1.910834 a one
data.groupby("key2").agg(np.mean)

.dataframe thead tr:only-child th { text-align: right }
.dataframe thead th { text-align: left }
.dataframe tbody tr th { vertical-align: top }

data1 data2
key2
one -0.808095 -0.983658
two -0.428699 -0.677738

当然, 这个等价于:

data.groupby("key2").mean()

.dataframe thead tr:only-child th { text-align: right }
.dataframe thead th { text-align: left }
.dataframe tbody tr th { vertical-align: top }

data1 data2
key2
one -0.808095 -0.983658
two -0.428699 -0.677738

原理: 聚合函数会在group后的每个切片上(group后的每一行或每一列)计算出值.

我们也可以自定义函数:

data.groupby("key2").agg(lambda x: x.max() - x.min())

.dataframe thead tr:only-child th { text-align: right }
.dataframe thead th { text-align: left }
.dataframe tbody tr th { vertical-align: top }

data1 data2
key2
one 1.876454 1.719153
two 4.544147 0.310511

他会在每个分组的每个列上调用这个函数.

data.groupby("key2").agg([np.mean, np.max,np.min])

.dataframe thead tr:only-child th { text-align: right }
.dataframe thead th { text-align: left }
.dataframe tbody tr th { vertical-align: top }

data1 data2
mean amax amin mean amax amin
key2
one -0.808095 0.441278 -1.435176 -0.983658 -0.191682 -1.910834
two -0.428699 1.843375 -2.700772 -0.677738 -0.522482 -0.832993
data.groupby("key2").agg([("平均值:", np.mean), ("最大值",np.max), ("最小值",np.min)]).rename({"one": "第一组", "two":"第二组"})

.dataframe thead tr:only-child th { text-align: right }
.dataframe thead th { text-align: left }
.dataframe tbody tr th { vertical-align: top }

data1 data2
平均值: 最大值 最小值 平均值: 最大值 最小值
key2
第一组 -0.808095 0.441278 -1.435176 -0.983658 -0.191682 -1.910834
第二组 -0.428699 1.843375 -2.700772 -0.677738 -0.522482 -0.832993
# 对不同列用不同的分组函数
data.groupby("key2").agg({"data1":[("平均值:", np.mean), ("最大值",np.max)], "data2":[("最小值",np.min)]}).rename({"one": "第一组", "two":"第二组"})

.dataframe thead tr:only-child th { text-align: right }
.dataframe thead th { text-align: left }
.dataframe tbody tr th { vertical-align: top }

data2 data1
最小值 平均值: 最大值
key2
第一组 -1.910834 -0.808095 0.441278
第二组 -0.832993 -0.428699 1.843375

transform

transform是一个矢量化的函数, 如果最后我们得到的值和分组切片不一致, 会进行广播:

data

.dataframe thead tr:only-child th { text-align: right }
.dataframe thead th { text-align: left }
.dataframe tbody tr th { vertical-align: top }

data1 data2 key1 key2
0 0.441278 -0.848457 a one
1 1.843375 -0.522482 a two
2 -1.435176 -0.191682 b one
3 -2.700772 -0.832993 b two
4 -1.430386 -1.910834 a one
data.groupby("key1").transform(np.mean)

.dataframe thead tr:only-child th { text-align: right }
.dataframe thead th { text-align: left }
.dataframe tbody tr th { vertical-align: top }

data1 data2
0 0.284756 -1.093924
1 0.284756 -1.093924
2 -2.067974 -0.512338
3 -2.067974 -0.512338
4 0.284756 -1.093924

仔细看, 0,1, 4一组, 2,3一组, 发生了广播.

现在有个需求,按分组减去均值.

data.groupby("key1").transform(lambda x: x - x.mean())

.dataframe thead tr:only-child th { text-align: right }
.dataframe thead th { text-align: left }
.dataframe tbody tr th { vertical-align: top }

data1 data2
0 0.156523 0.245468
1 1.558619 0.571442
2 0.632798 0.320656
3 -0.632798 -0.320656
4 -1.715142 -0.816910

a, b分组的各列都减去了他们的均值, 不信, 来看:

data.groupby("key1").transform(lambda x: x - x.mean()).groupby([1, 1, 0,0, 1]).mean()

.dataframe thead tr:only-child th { text-align: right }
.dataframe thead th { text-align: left }
.dataframe tbody tr th { vertical-align: top }

data1 data2
0 1.110223e-16 -5.551115e-17
1 7.401487e-17 -1.110223e-16

apply

这个函数是transform的加强版, transform只能返回和原来切片大小一样大的, 但apply是可以任意的. 其实我们之前就用过apply函数, 我们知道, apply是作用在列(行)上的, applymap是作用在函数上的.

data = DataFrame({"key1": [‘a‘, ‘a‘, ‘b‘, ‘b‘, ‘a‘], "key2": [‘one‘, ‘two‘, ‘one‘, ‘two‘, ‘one‘], ‘data1‘: np.random.randn(5), ‘data2‘: np.random.randn(5)})
data

.dataframe thead tr:only-child th { text-align: right }
.dataframe thead th { text-align: left }
.dataframe tbody tr th { vertical-align: top }

data1 data2 key1 key2
0 -0.312694 0.073574 a one
1 -0.902065 -0.854249 a two
2 -0.440915 0.228551 b one
3 -0.406243 -0.878505 b two
4 1.812926 -0.114598 a one

如果我们要找出one, 和two分组中选出data2最大的前两个呢?

data.groupby(‘key2‘).apply(lambda x: x.sort_values(by=‘data2‘)[-2:])

.dataframe thead tr:only-child th { text-align: right }
.dataframe thead th { text-align: left }
.dataframe tbody tr th { vertical-align: top }

data1 data2 key1 key2
key2
one 0 -0.312694 0.073574 a one
2 -0.440915 0.228551 b one
two 3 -0.406243 -0.878505 b two
1 -0.902065 -0.854249 a two

去掉group层次索引:

data.groupby(‘key2‘, group_keys=False).apply(lambda x: x.sort_values(by=‘data2‘)[-2:])

.dataframe thead tr:only-child th { text-align: right }
.dataframe thead th { text-align: left }
.dataframe tbody tr th { vertical-align: top }

data1 data2 key1 key2
0 -0.312694 0.073574 a one
2 -0.440915 0.228551 b one
3 -0.406243 -0.878505 b two
1 -0.902065 -0.854249 a two

总结一下: apply就是把分完组的切片挨个(按行, 按列, 或者整体)调用我们的函数, 最后再把结果合并起来.

利用groupby技术多进程处理DataFrame

我们这里要教大家用一种groupby技术, 来实现对DataFrame并行处理.

pip install joblib

因为我们windows系统的限制, 我们的代码是在linux上运行的:


import math
from joblib import Parallel, delayed
from pandas import DataFrame
import pandas as pd
import numpy as np
import time

begin = time.time()
test = DataFrame(np.random.randn(10000000, 10))
test_other = test.copy()
groups = test.groupby(lambda x: x % 8)

def func(x):
    return x.applymap(lambda y: math.pow(y, 4))

pd.concat(Parallel(n_jobs=8)(delayed(func)(group) for name, group in groups))
print(time.time() - begin)

begin = time.time()
test_other.applymap(lambda x: math.pow(x, 4))
print(time.time() - begin)

运算结果为:

23.35878014564514

62.76386260986328

速度大概提升了2.5倍, 还是很不错的.

原文地址:https://www.cnblogs.com/songfy/p/8449920.html

时间: 2024-10-10 22:08:14

pandas中的分组技术的相关文章

GPRS GPRS(General Packet Radio Service)是通用分组无线服务技术的简称,它是GSM移动电话用户可用的一种移动数据业务,属于第二代移动通信中的数据传输技术

GPRS 锁定 本词条由“科普中国”百科科学词条编写与应用工作项目 审核 . GPRS(General Packet Radio Service)是通用分组无线服务技术的简称,它是GSM移动电话用户可用的一种移动数据业务,属于第二代移动通信中的数据传输技术.GPRS可说是GSM的延续.GPRS和以往连续在频道传输的方式不同,是以封包(Packet)式来传输,因此使用者所负担的费用是以其传输资料单位计算,并非使用其整个频道,理论上较为便宜.GPRS的传输速率可提升至56甚至114Kbps.[1]

.net中对象序列化技术浅谈

.net中对象序列化技术浅谈 2009-03-11 阅读2756评论2 序列化是将对象状态转换为可保持或传输的格式的过程.与序列化相对的是反序列化,它将流转换为对象.这两个过程结合起来,可以轻松地存储和传输数 据.例如,可以序列化一个对象,然后使用 HTTP 通过 Internet 在客户端和服务器之间传输该对象.反之,反序列化根据流重新构造对象.此外还可以将对象序列化后保存到本地,再次运行的时候可以从本地文件 中“恢复”对象到序列化之前的状态.在.net中有提供了几种序列化的方式:二进制序列化

pandas聚合和分组运算之groupby

pandas提供了一个灵活高效的groupby功能,它使你能以一种自然的方式对数据集进行切片.切块.摘要等操作.根据一个或多个键(可以是函数.数组或DataFrame列名)拆分pandas对象.计算分组摘要统计,如计数.平均值.标准差,或用户自定义函数.对DataFrame的列应用各种各样的函数.应用组内转换或其他运算,如规格化.线性回归.排名或选取子集等.计算透视表或交叉表.执行分位数分析以及其他分组分析. 1.首先来看看下面这个非常简单的表格型数据集(以DataFrame的形式): impo

绘图与可视化--pandas中的绘图函数

matplotlib是一种比较低级的工具,要组装一张图表,你得用它得各种基础组件才行:数据展示(即图表类型:线型图.柱状图.盒型图.散布图.等值线图等).图例.标题.刻度标签以及其它注释型信息. 在pandas中,有行标签.列标签及分组信息,要绘制一张图,需要很多matplotlib代码.pandas有很多能够利用DataFrame对象数据组织特点来创建标准图表的高级绘图方法. 1.1 线型图 Series和DataFrame都有一个用于生成各类图表的plot方法,默认情况下,生成的是线型图.

OS X 和iOS 中的多线程技术(上)

OS X 和iOS 中的多线程技术(上) 本文梳理了OS X 和iOS 系统中提供的多线程技术.并且对这些技术的使用给出了一些实用的建议. 多线程的目的:通过并发执行提高 CPU 的使用效率,进而提供程序运行效率. 1.线程和进程 进程 什么是进程 进程是指在计算机系统中正在运行的一个应用程序 每个进程之间是独立的,每个进程均运行中其专用且受保护的内存空间内 比如同时打开 Xcode .Safari ,系统就会分别启动两个进程 通过活动监视器可以查看Mac系统中所开启的进程 线程 什么是线程 一

Android中直播视频技术探究之---基础核心类ByteBuffer解析

一.前言 前一篇文章我们介绍了Android中直播视频技术的基础大纲知识,这里就开始一一讲解各个知识点,首先主要来看一下视频直播中的一个重要的基础核心类:ByteBuffer,这个类看上去都知道了,是字节缓冲区处理字节的,这个类的功能非常强大,也在各个场景都有用到,比如网络数据底层处理,特别是结合网络通道信息处理的时候,还有就是后面要说到的OpenGL技术也要用到,当然在视频处理中也是很重要的,因为要处理视频流信息,比如在使用MediaCodec进行底层的视频流编码的时候,处理的就是字节,我们如

在 PHP 中结合 Ajax 技术进行图片上传

前面几则日志中讲述了在 PHP 中上传文件,相信大家对 PHP 中如何进行文件上传已经初步掌握.本文来继续探讨在 PHP 中上传文件的技术,不同的是,本次上传将仅限于图片文件的上传,并且将采用 Ajax 技术. 本例将要实现这样的效果:当用户选择图片,开始上传后,后台上传完成时,随即会显示到当前页面.由于,从开始上传到上传完成,再到图片显示均在一个页面上 完成(从表面上看).所以使用 Ajax 技术是必须的.但如何使用这些操作在一个页面上来完成呢?考虑到这样的情况,当文件开始上传后,便开始打开

VC中利用多线程技术实现线程之间的通信

文章来源:[url]http://www.programfan.com/article/showarticle.asp?id=2951[/url] 当前流行的Windows操作系统能同时运行几个程序(独立运行的程序又称之为进程),对于同一个程序,它又可以分成若干个独立的执行流,我们称之为线程,线程提供了多任务处理的能力.用进程和线程的观点来研究软件是当今普遍采用的方法,进程和线程的概念的出现,对提高软件的并行性有着重要的意义.现在的大型应用软件无一不是多线程多任务处理,单线程的软件是不可想象的.

终于把区块链与物流的关联搞清楚了 区块链的分类 物流业中区块链技术应用的案例

原文 区块链的分类 区块链可以分为三类:公有链.私有链.联盟链. 1.公有链无官方组织及管理机构,无中心服务器,参与的节点按照系统规则自由接入网络.不受控制,节点间基于共识机制开展工作. 2.私有链建立在某个企业内部,系统的运作规则根据企业要求进行设定,修改甚至是读取权限仅限于少数节点,同时仍保留着区块链的真实性和部分去中心化的特性. 3.联盟链由若干机构联合发起,介于公有链和私有链之间,兼具部分去中心化的特性. 去中心化是区块链的最重要特征 区块链技术提供了一种无需信任单个节点.还能创建共识网