NumPy 广播(Broadcast)与pandas基础知识

NumPy 广播(Broadcast)

广播(Broadcast)是 numpy 对不同形状(shape)的数组进行数值计算的方式, 对数组的算术运算通常在相应的元素上进行。如果两个数组 a 和 b 形状相同,即满足 a.shape == b.shape,那么 a*b 的结果就是 a 与 b 数组对应位相乘。这要求维数相同,且各维度的长度相同。

import numpy as np
a=np.arange(6).reshape(2,3)
print('原始数组是:')
print(a)
print('\n')
for x in np.nditer(a):
    print(x,end=", ")
print("\n")

b = np.arange(6).reshape(2,3)
print("b=",b)
c=b.T
print("c=",c)
for x in np.nditer(c):
    print(x, end=", ")
print("\n")

for x in np.nditer(a.T.copy(order='C')):
    print(x,end=", ")
print("\n")
原始数组是:
[[0 1 2]
 [3 4 5]]


0, 1, 2, 3, 4, 5, 

b= [[0 1 2]
 [3 4 5]]
c= [[0 3]
 [1 4]
 [2 5]]
0, 1, 2, 3, 4, 5, 

0, 3, 1, 4, 2, 5, 

控制遍历顺序

1、for x in np.nditer(a, order=‘F’):Fortran order,即是列序优先;
2、for x in np.nditer(a.T, order=‘C’):C order,即是行序优先;

import numpy as np

a=np.arange(0,60,5)
a=a.reshape(3,4)
print("原始数组是:")
print(a)
print("\n")
print("原始数组的转置是:")
b=a.T
print(b)
print("\n")
print("以C风格顺序排序:")
c=b.copy(order='C')
print(c)
for x in np.nditer(c):
    print(x,end=", ")
print("\n")
print("以F风格顺序排序:")
c=b.copy(order='F')
print(c)
for x in np.nditer(c):
    print(x, end=", ")

执行结果:

原始数组是:
[[ 0  5 10 15]
 [20 25 30 35]
 [40 45 50 55]]


原始数组的转置是:
[[ 0 20 40]
 [ 5 25 45]
 [10 30 50]
 [15 35 55]]


以C风格顺序排序:
[[ 0 20 40]
 [ 5 25 45]
 [10 30 50]
 [15 35 55]]
0, 20, 40, 5, 25, 45, 10, 30, 50, 15, 35, 55, 

以F风格顺序排序:
[[ 0 20 40]
 [ 5 25 45]
 [10 30 50]
 [15 35 55]]
0, 5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 

修改数组中元素的值

nditer对象有另一个可选参数op_flags。默认情况下,nditer将视待迭代遍历的数组为只读对象(read-only),为了在遍历数组的同时,实现对数组元素值的修改,必须指定read-write或者write-only的模式

import numpy as np

a=np.arange(0,60,5)
a=a.reshape(3,4)
print("原始数组是:")
print(a)
print("\n")
for x in np.nditer(a, op_flags=["readwrite"]):
    x[...]=2*x
print("修改后的数组是:")
print(a)

执行结果:

原始数组是:
[[ 0  5 10 15]
 [20 25 30 35]
 [40 45 50 55]]


修改后的数组是:
[[  0  10  20  30]
 [ 40  50  60  70]
 [ 80  90 100 110]]

使用外部循环

nditer类的构造器拥有flags参数,它可以接受下列值:
c_index 可以跟踪 C 顺序的索引
f_index 可以跟踪 Fortran 顺序的索引
multi-index 每次迭代可以跟踪一种索引类型
external_loop 给出的值是具有多个值的一维数组,而不是零维数组

import numpy as np
a=np.arange(0,60,5)
a=a.reshape(3,4)
print("原始数组是:")
print(a)
print("\n")
print("修改后的数组是:")
for x in np.nditer(a, flags= ["external_loop"],order="F"):
    print(x, end=", ")

执行结果:

原始数组是:
[[ 0  5 10 15]
 [20 25 30 35]
 [40 45 50 55]]


修改后的数组是:
[ 0 20 40], [ 5 25 45], [10 30 50], [15 35 55], 

广播迭代

如果两个数组是可广播的,nditer 组合对象能够同时迭代它们。 假设数组 a 的维度为 3X4,数组 b 的维度为 1X4 ,则使用以下迭代器(数组 b 被广播到 a 的大小)。

import numpy as np
a=np.arange(0,60,5)
a=a.reshape(3,4)
print("第一个数组为: ")
print(a)
print("\n")
print("第二个数组为:")
b=np.array([1,2,3,4], dtype=int)
print(b)
print("\n")
print("修改后的数组为:")
for x,y in np.nditer([a,b]):
    print("%d:%d" % (x,y), end=", ")

执行结果:

第一个数组为: 
[[ 0  5 10 15]
 [20 25 30 35]
 [40 45 50 55]]


第二个数组为:
[1 2 3 4]


修改后的数组为:
0:1, 5:2, 10:3, 15:4, 20:1, 25:2, 30:3, 35:4, 40:1, 45:2, 50:3, 55:4, 

Numpy 数组操作

Numpy 中包含了一些函数用于处理数组,大概可分为以下几类:
1、修改数组形状
2、翻转数组
3、修改数组维度
4、连接数组
5、分割数组
6、数组元素的添加与删除

修改数组形状

函数 描述
reshape 不改变数据的条件下修改形状
flat 数组元素迭代器
flatten 返回一份数组拷贝,对拷贝所做的修改不会影响原始数组
ravel 返回展开数组
numpy.reshape
numpy.reshape 函数可以在不改变数据的条件下修改形状,格式如下: numpy.reshape(arr,newshape, order=‘C’)
arr:要修改形状的数组
newshape:整数或者整数数组,新的形状应当兼容原有形状
order:‘C’ – 按行,‘F’ – 按列,‘A’ – 原顺序,‘k’ – 元素在内存中的出现顺序。

import numpy as np

a=np.arange(8)
print("原始数组:")
print(a,end="")
print("\n")
b=a.reshape(4,2)
print("修改后的数组:")
print(b)

执行结果:

原始数组:
[0 1 2 3 4 5 6 7]

修改后的数组:
[[0 1]
 [2 3]
 [4 5]
 [6 7]]

n

umpy.ndarray.flat

numpy.ndarray.flat是一个数组元素迭代器,实例如下:

import numpy as np

a=np.arange(9).reshape(3,3)
print("原始数组:")
for row in a:
    print(row)

#对数组中每个元素进行处理,可以使用flat属性,该属性是一个数组元素迭代器f
print("迭代后的数组:")
for element in a.flat:
    print(element)

执行结果:

原始数组:
[0 1 2]
[3 4 5]
[6 7 8]
迭代后的数组:
0
1
2
3
4
5
6
7
8

n

umpy.ndarray.flatten

numpy.ndaray.flatten返回一份数组拷贝,对拷贝所做的修改不会影响原始数组,格式如下:
ndarray.flatten返回一份数组拷贝,对拷贝所做的修改不会影响原始数组,格式如下:
ndarray.flatten(order=‘C’)

import numpy as np

a=np.arange(8).reshape(2,4)

print("原始组:")
print(a)
print('\n')
print("展开的数组:")
print(a.flatten())
print("\n")
print("以F风格顺序展开的数组:")
print(a.flatten(order='F'))

执行结果:

原始组:
[[0 1 2 3]
 [4 5 6 7]]


展开的数组:
[0 1 2 3 4 5 6 7]


以F风格顺序展开的数组:
[0 4 1 5 2 6 3 7]
numpy.ravel

numpy.rave()展开的数组元素,顺序通常是"C风格",返回的是数组视图,修改会影响原始数组。该函数接受两个参数:
numpy.ravel(a,order=‘c’)
order:‘C’–按行,‘F’–按列,‘A’–原顺序,'K‘–元素在内存中的出现顺序。

import numpy as np

a=np.arange(8).reshape(2,4)
print('原数组:')
print(a)
print('\n')
print('调用ravel函数之后:')
print(a.ravel())
print('\n')

print("以F风格顺序调用ravel函数之后:")
print(a.ravel(order='F'))

执行结果:

原数组:
[[0 1 2 3]
 [4 5 6 7]]


调用ravel函数之后:
[0 1 2 3 4 5 6 7]


以F风格顺序调用ravel函数之后:
[0 4 1 5 2 6 3 7]

翻转数组

函数 描述
transpose 对换数组的维度
ndarray.T 和 self.transpose() 相同
rollaxis 向后滚动指定的轴
swapaxes 对换数组的两个轴

numpy.transpose
numpy.transpose函数用于对换数组的维度,格式如下:
参数说明:
1、arr:要操作的数组
2、axes:整数列表,对应维度,通常所有维度都会对换

import numpy as np

a=np.arange(12).reshape(3,4)
print("原数组:")
print(a)
print("\n")

print("对换数组:")
print(np.transpose(a))

执行结果:

原数组:
[[ 0  1  2  3]
 [ 4  5  6  7]
 [ 8  9 10 11]]


对换数组:
[[ 0  4  8]
 [ 1  5  9]
 [ 2  6 10]
 [ 3  7 11]]

numpy.ndarray.T类似numpy.transpose:

import numpy as np

a=np.arange(12).reshape(3,4)
print("原数组:")
print(a)

print("数组变更后: ")
print(a.T)

执行结果:

原数组:
[[ 0  1  2  3]
 [ 4  5  6  7]
 [ 8  9 10 11]]
数组变更后: 
[[ 0  4  8]
 [ 1  5  9]
 [ 2  6 10]
 [ 3  7 11]]
numpy.broadcast

numpy.broadcast 用于模仿广播的对象,它返回一个对象,该对象封装了将一个数组广播到另一个数组的结果。该函数使用两个数组作为输入参数,如下实例:

import numpy as np

x = np.array([[1], [2], [3]])
print(x)
y = np.array([4, 5, 6])
print(y)

# 对 y 广播 x
b = np.broadcast(x, y)
# 它拥有 iterator 属性,基于自身组件的迭代器元组

print('对 y 广播 x:')
r, c = b.iters

# Python3.x 为 next(context) ,Python2.x 为 context.next()
print(next(r), next(c))
print(next(r), next(c))
print('\n')
# shape 属性返回广播对象的形状

print('广播对象的形状:')
print(b.shape)
print('\n')
# 手动使用 broadcast 将 x 与 y 相加
b = np.broadcast(x, y)
c = np.empty(b.shape)

print('手动使用 broadcast 将 x 与 y 相加:')
print(c.shape)
print('\n')
c.flat = [u + v for (u, v) in b]

print('调用 flat 函数:')
print(c)
print('\n')
# 获得了和 NumPy 内建的广播支持相同的结果

print('x 与 y 的和:')
print(x + y)

执行结果:

[[1]
 [2]
 [3]]
[4 5 6]
对 y 广播 x:
1 4
1 5


广播对象的形状:
(3, 3)


手动使用 broadcast 将 x 与 y 相加:
(3, 3)


调用 flat 函数:
[[5. 6. 7.]
 [6. 7. 8.]
 [7. 8. 9.]]


x 与 y 的和:
[[5 6 7]
 [6 7 8]
 [7 8 9]]
numpy.concatenate

numpy.concatenate 函数用于沿指定轴连接相同形状的两个或多个数组,格式如下:
numpy.concatenate((a1, a2, …), axis)
参数说明:
a1, a2, …:相同类型的数组
axis:沿着它连接数组的轴,默认为 0

import numpy as np

a=np.array([[1,2],[3,4]])

print('第一个数组:')
print(a)
print('\n')
b=np.array([[5,6],[7,8]])

print('第二个数组:')
print(b)
print('\n')
print('沿轴0连接两个数组:')
print(np.concatenate((a,b)))
print('\n')
print('沿轴1连接两个数组:')
print(np.concatenate((a,b),axis=1))

执行结果:

第一个数组:
[[1 2]
 [3 4]]


第二个数组:
[[5 6]
 [7 8]]


沿轴0连接两个数组:
[[1 2]
 [3 4]
 [5 6]
 [7 8]]


沿轴1连接两个数组:
[[1 2 5 6]
 [3 4 7 8]]
numpy.hstack

numpy.hstack 是 numpy.stack 函数的变体,它通过水平堆叠来生成数组。

import numpy as np

a=np.array([[1,2],[3,4]])

print("第一个数组:")
print(a)
print('\n')
b=np.array([[5,6],[7,8]])

print("第个数组:")
print(b)
print('\n')

print("沿轴0堆叠两个数组:")
print(np.stack((a,b),0))
print('\n')
print("沿轴1堆叠两个数组:")
print(np.stack((a,b),1))

执行结果:

第一个数组:
[[1 2]
 [3 4]]


第个数组:
[[5 6]
 [7 8]]


沿轴0堆叠两个数组:
[[[1 2]
  [3 4]]

 [[5 6]
  [7 8]]]


沿轴1堆叠两个数组:
[[[1 2]
  [5 6]]

 [[3 4]
  [7 8]]]
numpy.hstack

numpy.hstack 是 numpy.stack 函数的变体,它通过水平堆叠来生成数组。

import numpy as np

a=np.array([[1,2],[3,4]])

print("第一个数组:")
print(a)
print('\n')
b=np.array([[5,6],[7,8]])

print("第个数组:")
print(b)
print('\n')

print("水平堆叠:")
print(np.hstack((a,b)))
print('\n')

执行结果:

第一个数组:
[[1 2]
 [3 4]]


第个数组:
[[5 6]
 [7 8]]


水平堆叠:
[[1 2 5 6]
 [3 4 7 8]]
numpy.vstack

numpy.vstack 是 numpy.stack 函数的变体,它通过垂直堆叠来生成数组。

import numpy as np

a=np.array([[1,2],[3,4]])

print("第一个数组:")
print(a)
print('\n')
b=np.array([[5,6],[7,8]])

print("第个数组:")
print(b)
print('\n')

print("水平堆叠:")
print(np.vstack((a,b)))
print('\n')

执行结果:

第一个数组:
[[1 2]
 [3 4]]


第个数组:
[[5 6]
 [7 8]]


水平堆叠:
[[1 2]
 [3 4]
 [5 6]
 [7 8]]

numpy.hsplit

numpy.hsplit 函数用于水平分割数组,通过指定要返回的相同形状的数组数量来拆分原数组。

import numpy as np
harr = np.floor(10*np.random.random((2,6)))
print("原array:")
print(harr)

print("拆分后:")
print(np.hsplit(harr,3))

执行结果:

原array:
[[0. 4. 4. 8. 3. 0.]
 [1. 8. 6. 0. 9. 1.]]
拆分后:
[array([[0., 4.],
       [1., 8.]]), array([[4., 8.],
       [6., 0.]]), array([[3., 0.],
       [9., 1.]])]
numpy.vsplit

numpy.vsplit 沿着垂直轴分割,其分割方式与hsplit用法相同。

import numpy as np
harr = np.arange(16).reshape(4,4)
print("原array:")
print(harr)

print("竖直分割后:")
print(np.vsplit(harr,2))

执行结果:

原array:
[[ 0  1  2  3]
 [ 4  5  6  7]
 [ 8  9 10 11]
 [12 13 14 15]]
竖直分割后:
[array([[0, 1, 2, 3],
       [4, 5, 6, 7]]), array([[ 8,  9, 10, 11],
       [12, 13, 14, 15]])]

数组元素的添加与删除

函数 元素及描述
resize 返回指定形状的新数组
append 将值添加到数组末尾
insert 沿指定轴将值插入到指定下标之前
delete 删掉某个轴的子数组,并返回删除后的新数组
unique 查找数组内的唯一元素
numpy.resize
numpy.resize 函数返回指定大小的新数组。
如果新数组大小大于原始大小,则包含原始数组中的元素的副本。
numpy.resize(arr, shape)
numpy.resize
numpy.resize 函数返回指定大小的新数组。

如果新数组大小大于原始大小,则包含原始数组中的元素的副本。
numpy.resize(arr, shape)

import numpy as np

a = np.array([[1, 2, 3], [4, 5, 6]])

print('第一个数组:')
print(a)
print('\n')
print ('第一个数组的形状:')
print(a.shape)
b=np.resize(a,(3,2))
print("b:",np.resize(a,(3,2)))
print(b.shape)
c=np.resize(b,(3,3))
print("c:",c)

执行结果:

第一个数组:
[[1 2 3]
 [4 5 6]]


第一个数组的形状:
(2, 3)
b: [[1 2]
 [3 4]
 [5 6]]
(3, 2)
c: [[1 2 3]
 [4 5 6]
 [1 2 3]]

numpy.append

numpy.append 函数在数组的末尾添加值。 追加操作会分配整个数组,并把原来的数组复制到新数组中。 此外,输入数组的维度必须匹配否则将生成ValueError。append 函数返回的始终是一个一维数组。
numpy.append(arr, values, axis=None)

import numpy as np
a=np.array([[1,2,3],[4,5,6]])

print ('第一个数组:')
print (a)
print ('\n')

print ('向数组添加元素:')
print(np.append(a,[7,8,9]))

print ('沿轴 0 添加元素:')
print(np.append(a,[[7,8,9]],axis=0))

print ('沿轴 1 添加元素:')
print(np.append(a,[[5,5,5],[7,8,9]],axis=1))

执行结果:

第一个数组:
[[1 2 3]
 [4 5 6]]


向数组添加元素:
[1 2 3 4 5 6 7 8 9]
沿轴 0 添加元素:
[[1 2 3]
 [4 5 6]
 [7 8 9]]
沿轴 1 添加元素:
[[1 2 3 5 5 5]
 [4 5 6 7 8 9]]
numpy.insert

numpy.insert 函数在给定索引之前,沿给定轴在输入数组中插入值。
如果值的类型转换为要插入,则它与输入数组不同。 插入没有原地的,函数会返回一个新数组。 此外,如果未提供轴,则输入数组会被展开。
numpy.insert(arr, obj, values, axis)

import numpy as np

a = np.array([[1, 2], [3, 4], [5, 6]])

print('第一个数组:')
print(a)
print('\n')

print('未传递 Axis 参数。 在插入之前输入数组会被展开。')
print(np.insert(a,3,[11,12]))
print('传递了 Axis 参数。 会广播值数组来配输入数组。')

print('沿轴 0 广播:')
print(np.insert(a,1,[11],axis=0))
print ('沿轴 1 广播:')
print(np.insert(a,1,[11],axis=1))

执行结果:

第一个数组:
[[1 2]
 [3 4]
 [5 6]]


未传递 Axis 参数。 在插入之前输入数组会被展开。
[ 1  2  3 11 12  4  5  6]
传递了 Axis 参数。 会广播值数组来配输入数组。
沿轴 0 广播:
[[ 1  2]
 [11 11]
 [ 3  4]
 [ 5  6]]
沿轴 1 广播:
[[ 1 11  2]
 [ 3 11  4]
 [ 5 11  6]]
numpy.delete

numpy.delete 函数返回从输入数组中删除指定子数组的新数组。 与 insert() 函数的情况一样,如果未提供轴参数,则输入数组将展开。
Numpy.delete(arr, obj, axis)

import numpy as np

a = np.arange(12).reshape(3, 4)

print('第一个数组:')
print(a)
print('\n')

print('未传递 Axis 参数。 在插入之前输入数组会被展开。')
print(np.delete(a,5))
print ('删除第二列:')
print(np.delete(a,1,axis=1))
print ('包含从数组中删除的替代值的切片:')
a = np.array([1,2,3,4,5,6,7,8,9,10])
print(np.delete(a,np.s_[::2]))

执行结果:

第一个数组:
[[ 0  1  2  3]
 [ 4  5  6  7]
 [ 8  9 10 11]]


未传递 Axis 参数。 在插入之前输入数组会被展开。
[ 0  1  2  3  4  6  7  8  9 10 11]
删除第二列:
[[ 0  2  3]
 [ 4  6  7]
 [ 8 10 11]]
包含从数组中删除的替代值的切片:
[ 2  4  6  8 10]

numpy.unique

numpy.unique 函数用于去除数组中的重复元素。
numpy.unique(arr, return_index, return_inverse, return_counts)
arr:输入数组,如果不是一维数组则会展开
return_index:如果为true,返回新列表元素在旧列表中的位置(下标),并以列表形式储
return_inverse:如果为true,返回旧列表元素在新列表中的位置(下标),并以列表形式储
return_counts:如果为true,返回去重数组中的元素在原数组中的出现次数

import numpy as np

a = np.array([5, 2, 6, 2, 7, 5, 6, 8, 2, 9])

print('第一个数组:')
print(a)
print('\n')

print('第一个数组的去重值:')
u=np.unique(a)
print(u)
print ('去重数组的索引数组:')
u,indices=np.unique(a,return_index=True)
print(indices)
print ('我们可以看到每个和原数组下标对应的数值:')
print (a)
print ('去重数组的下标:')
u,indices = np.unique(a,return_inverse = True)
print (u)
print ('下标为:')
print (indices)
print ('\n')
print ('使用下标重构原数组:')
print (u[indices])
print ('\n')
print ('返回去重元素的重复数量:')
u,indices = np.unique(a,return_counts = True)
print (u)
print (indices)

执行结果:

第一个数组:
[5 2 6 2 7 5 6 8 2 9]


第一个数组的去重值:
[2 5 6 7 8 9]
去重数组的索引数组:
[1 0 2 4 7 9]
我们可以看到每个和原数组下标对应的数值:
[5 2 6 2 7 5 6 8 2 9]
去重数组的下标:
[2 5 6 7 8 9]
下标为:
[1 0 2 0 3 1 2 4 0 5]


使用下标重构原数组:
[5 2 6 2 7 5 6 8 2 9]


返回去重元素的重复数量:
[2 5 6 7 8 9]
[3 2 2 1 1 1]

1、pandas创建

import pandas as pd

df = pd.DataFrame({'年龄':[19,18,16,14],'工作':['science','teacher','worker','flyer']},index=['zhangsan','lisi','wangwu','tianliu'])
print(df)

执行结果:

          年龄       工作
zhangsan  19  science
lisi      18  teacher
wangwu    16   worker
tianliu   14    flyer

读取

import pandas as pd
df = pd.read_excel('需求.xlsx')
df.head()
print(df)

执行结果:

   序列    公司
0   1  方大碳素
1   2  金路集团
2   3  中国宝安
3   4  华丽家族
4   5  中泰化学
5   6  乐通股份
6   7    康得
7   8  东旭光电

存储

import pandas as pd

df = pd.DataFrame({'年龄':[19,18,16,14],'工作':['science','teacher','worker','flyer']},index=['zhangsan','lisi','wangwu','tianliu'])
print(df)
#df.to_csv("工作布.csv")

df.to_excel("工作布1.xlsx")

查看

import pandas as pd

df = pd.DataFrame({'年龄':[19,18,16,14],'工作':['science','teacher','worker','flyer']},index=['zhangsan','lisi','wangwu','tianliu'])
#查看第一行
print(df.head(1))

print(df)
#查看最后两行
print(df.tail(2))

结果:

          年龄       工作
zhangsan  19  science
          年龄       工作
zhangsan  19  science
lisi      18  teacher
wangwu    16   worker
tianliu   14    flyer
         年龄      工作
wangwu   16  worker
tianliu  14   flyer

格式查看

df.info()帮助我们一步摸清各列数据的类型,以及缺失情况:
执行结果:

<class 'pandas.core.frame.DataFrame'>
Index: 4 entries, zhangsan to tianliu
Data columns (total 2 columns):
 #   Column  Non-Null Count  Dtype 
---  ------  --------------  ----- 
 0   年龄      4 non-null      int64 
 1   工作      4 non-null      object
dtypes: int64(1), object(1)
memory usage: 96.0+ bytes

统计信息

快速计算数值型数据的关键统计指标,像平均数、中位数、标准差等等。
df.describe()

在这里插入代码片
年龄
count   4.000000
mean   16.750000
std     2.217356
min    14.000000
25%    15.500000
50%    17.000000
75%    18.250000
max    19.000000

其中count是统计每一列的有多少个非空数值,mean、std、min、max对应的分别是该列的均值、标准差、最小值和最大值,25%、50%、75%对应的则是分位数。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值