大数据:Numpy基础应用详解

Numpy基础应用

Numpy 是一个开源的 Python 科学计算库,用于快速处理任意维度的数组。Numpy 支持常见的数组和矩阵操作,对于同样的数值计算任务,使用 NumPy 不仅代码要简洁的多,而且 NumPy 的性能远远优于原生 Python,基本是一个到两个数量级的差距,而且数据量越大,NumPy 的优势就越明显。

Numpy 最为核心的数据类型是ndarray,使用ndarray可以处理一维、二维和多维数组,该对象相当于是一个快速而灵活的大数据容器。NumPy 底层代码使用 C 语言编写,解决了 GIL 的限制,ndarray在存取数据的时候,数据与数据的地址都是连续的,这确保了可以进行高效率的批量操作,远远优于 Python 中的list;另一方面ndarray对象提供了更多的方法来处理数据,尤其是和统计相关的方法,这些方法也是 Python 原生的list没有的。

全部文章请访问专栏:《Python全栈教程(0基础)》
再推荐一下最近热更的:《大厂测试高频面试题详解》 该专栏对近年高频测试相关面试题做详细解答,结合自己多年工作经验,以及同行大佬指导总结出来的。旨在帮助测试、python方面的同学,顺利通过面试,拿到自己满意的offer!

文章目录

    • Numpy基础应用
      • 准备工作
      • 创建数组对象
        • 一维数组
        • 二维数组
        • 多维数组
      • 数组对象的属性
      • 数组的索引和切片
        • 案例:通过数组切片处理图像
      • 数组对象的方法
        • 统计方法
        • 其他方法


准备工作

  1. 启动Notebook

    jupyter notebook
    

    提示:在启动Notebook之前,建议先安装好数据分析相关依赖项,包括之前提到的三大神器以及相关依赖项,包括:numpypandasmatplotlibopenpyxl等。如果使用Anaconda,则无需单独安装。

  2. 导入

    import numpy as np
    import pandas as pd
    import matplotlib.pyplot as plt
    

    说明:如果已经启动了 Notebook 但尚未安装相关依赖库,例如尚未安装numpy,可以在 Notebook 的单元格中输入!pip install numpy并运行该单元格来安装 NumPy,也可以一次性安装多个三方库,需要在单元格中输入%pip install numpy pandas matplotlib。注意上面的代码,我们不仅导入了NumPy,还将 pandas 和 matplotlib 库一并导入了。

创建数组对象

创建ndarray对象有很多种方法,下面就如何创建一维数组、二维数组和多维数组进行说明。

一维数组

  • 方法一:使用array函数,通过list创建数组对象

    代码:

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

    输出:

    array([1, 2, 3, 4, 5])
    
  • 方法二:使用arange函数,指定取值范围创建数组对象

    代码:

    array2 = np.arange(0, 20, 2)
    array2
    

    输出:

    array([ 0,  2,  4,  6,  8, 10, 12, 14, 16, 18])
    
  • 方法三:使用linspace函数,用指定范围均匀间隔的数字创建数组对象

    代码:

    array3 = np.linspace(-5, 5, 101)
    array3
    

    输出:

    array([-5. , -4.9, -4.8, -4.7, -4.6, -4.5, -4.4, -4.3, -4.2, -4.1, -4. ,-3.9, -3.8, -3.7, -3.6, -3.5, -3.4, -3.3, -3.2, -3.1, -3. , -2.9,-2.8, -2.7, -2.6, -2.5, -2.4, -2.3, -2.2, -2.1, -2. , -1.9, -1.8,-1.7, -1.6, -1.5, -1.4, -1.3, -1.2, -1.1, -1. , -0.9, -0.8, -0.7,-0.6, -0.5, -0.4, -0.3, -0.2, -0.1,  0. ,  0.1,  0.2,  0.3,  0.4,0.5,  0.6,  0.7,  0.8,  0.9,  1. ,  1.1,  1.2,  1.3,  1.4,  1.5,1.6,  1.7,  1.8,  1.9,  2. ,  2.1,  2.2,  2.3,  2.4,  2.5,  2.6,2.7,  2.8,  2.9,  3. ,  3.1,  3.2,  3.3,  3.4,  3.5,  3.6,  3.7,3.8,  3.9,  4. ,  4.1,  4.2,  4.3,  4.4,  4.5,  4.6,  4.7,  4.8,4.9,  5. ])
    
  • 方法四:使用numpy.random模块的函数生成随机数创建数组对象

    产生10个 [ 0 , 1 ) [0, 1) [0,1)范围的随机小数,代码:

    array4 = np.random.rand(10)
    array4
    

    输出:

    array([0.45556132, 0.67871326, 0.4552213 , 0.96671509, 0.44086463,0.72650875, 0.79877188, 0.12153022, 0.24762739, 0.6669852 ])
    

    产生10个 [ 1 , 100 ) [1, 100) [1,100)范围的随机整数,代码:

    array5 = np.random.randint(1, 100, 10)
    array5
    

    输出:

    array([29, 97, 87, 47, 39, 19, 71, 32, 79, 34])
    

    产生20个 μ = 50 \mu=50 μ=50 σ = 10 \sigma=10 σ=10的正态分布随机数,代码:

    array6 = np.random.normal(50, 10, 20)
    array6
    

    输出:

    array([55.04155586, 46.43510797, 20.28371158, 62.67884053, 61.23185964,38.22682148, 53.17126151, 43.54741592, 36.11268017, 40.94086676,63.27911699, 46.92688903, 37.1593374 , 67.06525656, 67.47269463,23.37925889, 31.45312239, 48.34532466, 55.09180924, 47.95702787])
    

说明:创建一维数组还有很多其他的方式,比如通过读取字符串、读取文件、解析正则表达式等方式,这里我们暂不讨论这些方式,有兴趣的读者可以自行研究。

二维数组

  • 方法一:使用array函数,通过嵌套的list创建数组对象

    代码:

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

    输出:

    array([[1, 2, 3],[4, 5, 6]])
    
  • 方法二:使用zerosonesfull函数指定数组的形状创建数组对象

    使用zeros函数,代码:

    array8 = np.zeros((3, 4))
    array8
    

    输出:

    array([[0., 0., 0., 0.],[0., 0., 0., 0.],[0., 0., 0., 0.]])
    

    使用ones函数,代码:

    array9 = np.ones((3, 4))
    array9
    

    输出:

    array([[1., 1., 1., 1.],[1., 1., 1., 1.],[1., 1., 1., 1.]])
    

    使用full函数,代码:

    array10 = np.full((3, 4), 10)
    array10
    

    输出:

    array([[10, 10, 10, 10],[10, 10, 10, 10],[10, 10, 10, 10]])
    
  • 方法三:使用eye函数创建单位矩阵

    代码:

    array11 = np.eye(4)
    array11
    

    输出:

    array([[1., 0., 0., 0.],[0., 1., 0., 0.],[0., 0., 1., 0.],[0., 0., 0., 1.]])
    
  • 方法四:通过reshape将一维数组变成二维数组

    代码:

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

    输出:

    array([[1, 2, 3],[4, 5, 6]])
    

    提示reshapendarray对象的一个方法,使用reshape方法时需要确保调形后的数组元素个数与调形前数组元素个数保持一致,否则将会产生异常。

  • 方法五:通过numpy.random模块的函数生成随机数创建数组对象

    产生 [ 0 , 1 ) [0, 1) [0,1)范围的随机小数构成的3行4列的二维数组,代码:

    array13 = np.random.rand(3, 4)
    array13
    

    输出:

    array([[0.54017809, 0.46797771, 0.78291445, 0.79501326],[0.93973783, 0.21434806, 0.03592874, 0.88838892],[0.84130479, 0.3566601 , 0.99935473, 0.26353598]])
    

    产生 [ 1 , 100 ) [1, 100) [1,100)范围的随机整数构成的3行4列的二维数组,代码:

    array14 = np.random.randint(1, 100, (3, 4))
    array14
    

    输出:

    array([[83, 30, 64, 53],[39, 92, 53, 43],[43, 48, 91, 72]])
    

多维数组

  • 使用随机的方式创建多维数组

    代码:

    array15 = np.random.randint(1, 100, (3, 4, 5))
    array15
    

    输出:

    array([[[94, 26, 49, 24, 43],[27, 27, 33, 98, 33],[13, 73,  6,  1, 77],[54, 32, 51, 86, 59]],[[62, 75, 62, 29, 87],[90, 26,  6, 79, 41],[31, 15, 32, 56, 64],[37, 84, 61, 71, 71]],[[45, 24, 78, 77, 41],[75, 37,  4, 74, 93],[ 1, 36, 36, 60, 43],[23, 84, 44, 89, 79]]])
    
  • 将一维二维的数组调形为多维数组

    一维数组调形为多维数组,代码:

    array16 = np.arange(1, 25).reshape((2, 3, 4))
    array16
    

    输出:

    array([[[ 1,  2,  3,  4],[ 5,  6,  7,  8],[ 9, 10, 11, 12]],[[13, 14, 15, 16],[17, 18, 19, 20],[21, 22, 23, 24]]])
    

    二维数组调形为多维数组,代码:

    array17 = np.random.randint(1, 100, (4, 6)).reshape((4, 3, 2))
    array17
    

    输出:

    array([[[60, 59],[31, 80],[54, 91]],[[67,  4],[ 4, 59],[47, 49]],[[16,  4],[ 5, 71],[80, 53]],[[38, 49],[70,  5],[76, 80]]])
    
  • 读取图片获得对应的三维数组

    代码:

    array18 = plt.imread('guido.jpg')
    array18
    

    输出:

    array([[[ 36,  33,  28],[ 36,  33,  28],[ 36,  33,  28],...,[ 32,  31,  29],[ 32,  31,  27],[ 31,  32,  26]],[[ 37,  34,  29],[ 38,  35,  30],[ 38,  35,  30],...,[ 31,  30,  28],[ 31,  30,  26],[ 30,  31,  25]],[[ 38,  35,  30],[ 38,  35,  30],[ 38,  35,  30],...,[ 30,  29,  27],[ 30,  29,  25],[ 29,  30,  25]],...,[[239, 178, 123],[237, 176, 121],[235, 174, 119],...,[ 78,  68,  56],[ 75,  67,  54],[ 73,  65,  52]],[[238, 177, 120],[236, 175, 118],[234, 173, 116],...,[ 82,  70,  58],[ 78,  68,  56],[ 75,  66,  51]],[[238, 176, 119],[236, 175, 118],[234, 173, 116],...,[ 84,  70,  61],[ 81,  69,  57],[ 79,  67,  53]]], dtype=uint8)
    

    说明:上面的代码读取了当前路径下名为guido.jpg 的图片文件,计算机系统中的图片通常由若干行若干列的像素点构成,而每个像素点又是由红绿蓝三原色构成的,所以能够用三维数组来表示。读取图片用到了matplotlib库的imread函数。

数组对象的属性

  1. size属性:数组元素个数

    代码:

    array19 = np.arange(1, 100, 2)
    array20 = np.random.rand(3, 4)
    print(array19.size, array20.size)
    

    输出:

    50 12
    
  2. shape属性:数组的形状

    代码:

    print(array19.shape, array20.shape)
    

    输出:

    (50,) (3, 4)
    
  3. dtype属性:数组元素的数据类型

    代码:

    print(array19.dtype, array20.dtype)
    

    输出:

    int64 float64
    

    ndarray对象元素的数据类型可以参考如下所示的表格。

  4. ndim属性:数组的维度

    代码:

    print(array19.ndim, array20.ndim)
    

    输出:

    1 2
    
  5. itemsize属性:数组单个元素占用内存空间的字节数

    代码:

    array21 = np.arange(1, 100, 2, dtype=np.int8)
    print(array19.itemsize, array20.itemsize, array21.itemsize)
    

    输出:

    8 8 1
    

    说明:在使用arange创建数组对象时,通过dtype参数指定元素的数据类型。可以看出,np.int8代表的是8位有符号整数,只占用1个字节的内存空间,取值范围是 [ − 128 , 127 ] [-128,127] [128,127]

  6. nbytes属性:数组所有元素占用内存空间的字节数

    代码:

    print(array19.nbytes, array20.nbytes, array21.nbytes)
    

    输出:

    400 96 50
    
  7. flat属性:数组(一维化之后)元素的迭代器

    代码:

    from typing import Iterableprint(isinstance(array20.flat, np.ndarray), isinstance(array20.flat, Iterable))
    

    输出:

    False True
    
  8. base属性:数组的基对象(如果数组共享了其他数组的内存空间)

    代码:

    array22 = array19[:]
    print(array22.base is array19, array22.base is array21)
    

    输出:

    True False
    

    说明:上面的代码用到了数组的切片操作,它类似于 Python 中list类型的切片,但在细节上又不完全相同,下面会专门讲解这个知识点。通过上面的代码可以发现,ndarray切片后得到的新的数组对象跟原来的数组对象共享了内存中的数据,因此array22base属性就是array19对应的数组对象。

数组的索引和切片

和 Python 中的列表类似,NumPy 的ndarray对象可以进行索引和切片操作,通过索引可以获取或修改数组中的元素,通过切片可以取出数组的一部分。

  1. 索引运算(普通索引)

    一维数组,代码:

    array23 = np.array([1, 2, 3, 4, 5, 6, 7, 8, 9])
    print(array23[0], array23[array23.size - 1])
    print(array23[-array23.size], array23[-1])
    

    输出:

    1 9
    1 9
    

    二维数组,代码:

    array24 = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
    print(array24[2])
    print(array24[0][0], array24[-1][-1])
    print(array24[1][1], array24[1, 1])
    

    输出:

    [7 8 9]
    1 9
    5 5
    [[ 1  2  3][ 4 10  6][ 7  8  9]]
    

    代码:

    array24[1][1] = 10
    print(array24)
    array24[1] = [10, 11, 12]
    print(array24)
    

    输出:

    [[ 1  2  3][ 4 10  6][ 7  8  9]]
    [[ 1  2  3][10 11 12][ 7  8  9]]
    
  2. 切片运算(切片索引)

    切片是形如[开始索引:结束索引:步长]的语法,通过指定开始索引(默认值无穷小)、结束索引(默认值无穷大)和步长(默认值1),从数组中取出指定部分的元素并构成新的数组。因为开始索引、结束索引和步长都有默认值,所以它们都可以省略,如果不指定步长,第二个冒号也可以省略。一维数组的切片运算跟 Python 中的list类型的切片非常类似,此处不再赘述,二维数组的切片可以参考下面的代码,相信非常容易理解。

    代码:

    print(array24[:2, 1:])
    

    输出:

    [[2 3][5 6]]
    

    代码:

    print(array24[2])
    print(array24[2, :])
    

    输出:

    [7 8 9]
    [7 8 9]
    

    代码:

    print(array24[2:, :])
    

    输出:

    [[7 8 9]]
    

    代码:

    print(array24[:, :2])
    

    输出:

    [[1 2][4 5][7 8]]
    

    代码:

    print(array24[1, :2])
    print(array24[1:2, :2])
    

    输出:

    [4 5]
    [[4 5]]
    

    代码:

    print(array24[::2, ::2])
    

    输出:

    [[1 3][7 9]]
    

    代码:

    print(array24[::-2, ::-2])
    

    输出:

    [[9 7][3 1]]
    

    关于数组的索引和切片运算,大家可以通过下面的两张图来增强印象,这两张图来自《利用Python进行数据分析》一书,它是pandas库的作者 Wes McKinney 撰写的 Python 数据分析领域的经典教科书,有兴趣的读者可以购买和阅读原书。

  3. 花式索引(fancy index)

    花式索引(Fancy indexing)是指利用整数数组进行索引,这里所说的整数数组可以是 NumPy 的ndarray,也可以是 Python 中listtuple等可迭代类型,可以使用正向或负向索引。

    一维数组的花式索引,代码:

    array25 = np.array([50, 30, 15, 20, 40])
    array25[[0, 1, -1]]
    

    输出:

    array([50, 30, 40])
    

    二维数组的花式索引,代码:

    array26 = np.array([[30, 20, 10], [40, 60, 50], [10, 90, 80]])
    # 取二维数组的第1行和第3行
    array26[[0, 2]]
    

    输出:

    array([[30, 20, 10],[10, 90, 80]])
    

    代码:

    # 取二维数组第1行第2列,第3行第3列的两个元素
    array26[[0, 2], [1, 2]]
    

    输出:

    array([20, 80])
    

    代码:

    # 取二维数组第1行第2列,第3行第2列的两个元素
    array26[[0, 2], 1]
    

    输出:

    array([20, 90])
    
  4. 布尔索引

    布尔索引就是通过布尔类型的数组对数组元素进行索引,布尔类型的数组可以手动构造,也可以通过关系运算来产生布尔类型的数组。

    代码:

    array27 = np.arange(1, 10)
    array27[[True, False, True, True, False, False, False, False, True]]
    

    输出:

    array([1, 3, 4, 9])
    

    代码:

    array27 >= 5
    

    输出:

    array([False, False, False, False,  True,  True,  True,  True,  True])
    

    代码:

    # ~运算符可以实现逻辑变反,看看运行结果跟上面有什么不同
    ~(array27 >= 5)
    

    输出:

    array([ True,  True,  True,  True, False, False, False, False, False])
    

    代码:

    array27[array27 >= 5]
    

    输出:

    array([5, 6, 7, 8, 9])
    

提示:切片操作虽然创建了新的数组对象,但是新数组和原数组共享了数组中的数据,简单的说,如果通过新数组对象或原数组对象修改数组中的数据,其实修改的是同一块数据。花式索引和布尔索引也会创建新的数组对象,而且新数组复制了原数组的元素,新数组和原数组并不是共享数据的关系,这一点通过前面讲的数组的base属性也可以了解到,在使用的时候要引起注意。

案例:通过数组切片处理图像

学习基础知识总是比较枯燥且没有成就感的,所以我们还是来个案例为大家演示下上面学习的数组索引和切片操作到底有什么用。前面我们说到过,可以用三维数组来表示图像,那么通过图像对应的三维数组进行操作,就可以实现对图像的处理,如下所示。

读入图片创建三维数组对象。

guido_image = plt.imread('guido.jpg')
plt.imshow(guido_image)

对数组的0轴进行反向切片,实现图像的垂直翻转。

plt.imshow(guido_image[::-1])

对数组的1轴进行反向切片,实现图像的水平翻转。

plt.imshow(guido_image[:,::-1])

将 Guido 的头切出来。

plt.imshow(guido_image[30:350, 90:300])

数组对象的方法

统计方法

统计方法主要包括:sum()mean()std()var()min()max()argmin()argmax()cumsum()等,分别用于对数组中的元素求和、求平均、求标准差、求方差、找最大、找最小、求累积和等,请参考下面的代码。

array28 = np.array([1, 2, 3, 4, 5, 5, 4, 3, 2, 1])
print(array28.sum())
print(array28.mean())
print(array28.max())
print(array28.min())
print(array28.std())
print(array28.var())
print(array28.cumsum())

输出:

30
3.0
5
1
1.4142135623730951
2.0
[ 1  3  6 10 15 20 24 27 29 30]

其他方法

  1. all() / any()方法:判断数组是否所有元素都是True / 判断数组是否有为True的元素。

  2. astype()方法:拷贝数组,并将数组中的元素转换为指定的类型。

  3. dump()方法:保存数组到文件中,可以通过 NumPy 中的load()函数从保存的文件中加载数据创建数组。

    代码:

    array31.dump('array31-data')
    array32 = np.load('array31-data', allow_pickle=True)
    array32
    

    输出:

    array([[1, 2],[3, 4],[5, 6]])
    
  4. fill()方法:向数组中填充指定的元素。

  5. flatten()方法:将多维数组扁平化为一维数组。

    代码:

    array32.flatten()
    

    输出:

    array([1, 2, 3, 4, 5, 6])
    
  6. nonzero()方法:返回非0元素的索引。

  7. round()方法:对数组中的元素做四舍五入操作。

  8. sort()方法:对数组进行就地排序。

    代码:

    array33 = np.array([35, 96, 12, 78, 66, 54, 40, 82])
    array33.sort()
    array33
    

    输出:

    array([12, 35, 40, 54, 66, 78, 82, 96])
    
  9. swapaxes()transpose()方法:交换数组指定的轴。

    代码:

    # 指定需要交换的两个轴,顺序无所谓
    array32.swapaxes(0, 1)
    

    输出:

    array([[1, 3, 5],[2, 4, 6]])
    

    代码:

    # 对于二维数组,transpose相当于实现了矩阵的转置
    array32.transpose()
    

    输出:

    array([[1, 3, 5],[2, 4, 6]])
    
  10. tolist()方法:将数组转成Python中的list

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

设计HTML5表单

HTML5基于Web Forms 2.0标准对HTML4表单进行全面升级,在保持简便、易用的基础上,新增了很多控件和属性,从而减轻了开发人员的负担。表单为访问者提供了与网站进行互动的途径,完整的表单一般由控件和脚本两部分组成。 1、认识HTML…

Lombok的使用及注解含义

文章目录 一、简介二、如何使用2.1、在IDEA中安装Lombok插件2.2、添加maven依赖 三、常用注解3.1、Getter / Setter3.2、ToString3.3、NoArgsConstructor / AllArgsConstructor3.4、EqualsAndHashCode3.5、Data3.6、Value3.7、Accessors3.7.1、Accessors(chain true)3.7.2、Ac…

Open3D 最小二乘拟合平面(SVD分解法)

目录 一、算法原理二、代码实现三、结果展示1、点云2、拟合结果四、优秀博客本文由CSDN点云侠原创,原文链接。爬虫网站自重。 一、算法原理 本文实现矩阵奇异值分解方法的最小二乘拟合平面。原理如下: 对于得到的 n n

实现文件的拖放功能

文章目录 实现文件的拖放功能1 拖放文件至QT窗口1.1 实现方法1.2 效果演示 2 拖放文件至python脚本2.1 实现方法2.2 效果演示 实现文件的拖放功能 试想一下,我们希望将一个python项目文件夹或者脚本在IDE中打开,无论是去IDE中选择文件夹路径,…

[GAN] 使用GAN网络进行图片生成的“调参人”入门指南——生成向日葵图片

[GAN] 使用GAN网络进行图片生成的“炼丹人”日志——生成向日葵图片 文章目录 [GAN] 使用GAN网络进行图片生成的“炼丹人”日志——生成向日葵图片1. 写在前面:1.1 应用场景:1.2 数据集情况:1.3 实验原理讲解和分析(简化版&#x…

什么是前端框架?怎么学习? - 易智编译EaseEditing

前端框架是一种用于开发Web应用程序界面的工具集合,它提供了一系列预定义的代码和结构,以简化开发过程并提高效率。 前端框架通常包括HTML、CSS和JavaScript的库和工具,用于构建交互式、动态和响应式的用户界面。 学习前端框架可以让您更高效…

(7)(7.1) 使用航点和事件规划任务

文章目录 前言 7.1.1 设置Home位置 7.1.2 视频:制作并保存多路点任务 7.1.3 视频:加载已保存的多航点任务 7.1.4 使用说明 7.1.5 提示 7.1.6 自动网格 7.1.7 任务指令 7.1.8 任务结束 7.1.9 任务重置 7.1.10 MIS_OPTIONS 7.1.11 任务再出发 …

解决右键打印html只能识别1页的问题

hello,大家好久不见,昨天在开发中遇到了一个问题,就是在自己开发的网页中右键-->打印,由于页面内容过多,打印出来的内容只被识别到一页。 针对这一问题,查阅了好多资料最终解决啦。 1.问题重现 大家可以看到这个是我们开发的页面,公司需要…

【工程优化问题】基于鲸鱼、萤火虫、灰狼优化算法的张力、压缩弹簧设计问题研究(Matlab代码实现)

💥💥💞💞欢迎来到本博客❤️❤️💥💥 🏆博主优势:🌞🌞🌞博客内容尽量做到思维缜密,逻辑清晰,为了方便读者。 ⛳️座右铭&a…

【密码学】维京密码

维京密码 瑞典罗特布鲁纳巨石上的图案看起来毫无意义,但是它确实是一种维京密码。如果我们注意到每组图案中长笔画和短笔画的数量,将得到一组数字2、4、2、3、3、5、2、3、3、6、3、5。组合配对得到24、23、35、23、36、35。现在考虑如图1.4所示的内容&a…

SAP MM学习笔记23-购买发注的账户分配类型(勘定Category)

SAP中控制财务凭证过账科目的是 账号分配类型(勘定Category)栏目。 ・账号分配类型(勘定Category)有: 1,K 原价Center(成本中心。用于消耗物料采购 的过账) 2,E 得意先…

Linux 僵死进程

fork复制进程之后,会产生一个进程叫做子进程,被复制的进程就是父进程。不管父进程先结束,还是子进程先结束,对另外一个进程完全没有影响,父进程和子进程是两个不同的进程。 一、孤儿进程 现在有以下代码:…