【问题标题】:Pandas vs Numpy indexing: Why this fundamental difference in ordering of indices?Pandas 与 Numpy 索引:为什么索引排序存在这种根本差异?
【发布时间】:2019-12-30 03:13:01
【问题描述】:

Numpy:

import numpy as np
nparr = np.array([[1, 5],[2,6], [3, 7]])
print(nparr)
print(nparr[0])    #first choose the row 
print(nparr[0][1]) #second choose the column

按预期给出输出:

[[1 5]
 [2 6]
 [3 7]]

[1 5]

5

熊猫:

df = pd.DataFrame({
    'a': [1, 2, 3],
    'b': [5, 6, 7]
})
print(df)
print(df['a'])  #first choose the column !!!
print(df['a'][1])  #second choose the row !!!

给出以下输出:

   a  b
0  1  5
1  2  6
2  3  7

0    1
1    2
2    3
Name: a, dtype: int64

2

将 Pandas 数据框中“索引”的默认排序更改为列优先的根本原因是什么?失去一致性/直观性会给我们带来什么好处?

当然,如果我使用 iloc 函数,我们可以将其编码为类似于 Numpy 数组索引:

print(df)
print(df.iloc[0])     # first choose the row
print(df.iloc[0][1])  # second choose the column
   a  b
0  1  5
1  2  6
2  3  7

a    1
b    5
Name: 0, dtype: int64

5

【问题讨论】:

  • 我认为 DataFrame 由 Series 组成。系列/列可以在dtype 中有所不同。 numpy 具有结构化数组,其字段具有自己的数据类型。

标签: python pandas numpy dataframe


【解决方案1】:

因为 Numpy 的直觉是数学(更具体地说是矩阵,类似于 MATLAB),而 Pandas 的直觉是数据库(类似于 SQL)。 Numpy 按行和列(行在前,因为矩阵的元素(i, j) 表示ith 行和jth 列),而 Pandas 基于数据库的列工作,您可以在其中选择元素,即行。当然,正如您所提到的,您可以使用iloc 直接处理索引。

希望两者的范式/哲学差异有意义。

【讨论】:

    【解决方案2】:

    numpy 索引是多维的。 pandas 是面向表的,只有 2d(多索引变体除外)。

    In [42]: nparr = np.array([[1, 5],[2,6], [3, 7]])                               
    In [43]: nparr                                                                  
    Out[43]: 
    array([[1, 5],
           [2, 6],
           [3, 7]])
    In [44]: nparr[0]             # select a row                                                               
    Out[44]: array([1, 5])
    In [45]: nparr[:,0]           # select a column                                    
    Out[45]: array([1, 2, 3])
    In [46]: nparr[:,[0]]         # also a column, but keep 2d                                                  
    Out[46]: 
    array([[1],
           [2],
           [3]])
    In [47]: nparr[:2,[1,0]]      # more general - 2 rows, 2 columns (reordered)                                                  
    Out[47]: 
    array([[5, 1],
           [6, 2]])
    

    您的nparr[0][1] 更习惯写成nparr[0,1]

    此索引推广到 3d(及更高):

    In [48]: arr = np.arange(24).reshape(2,3,4)                                     
    In [49]: arr                                                                    
    Out[49]: 
    array([[[ 0,  1,  2,  3],
            [ 4,  5,  6,  7],
            [ 8,  9, 10, 11]],
    
           [[12, 13, 14, 15],
            [16, 17, 18, 19],
            [20, 21, 22, 23]]])
    In [50]: arr[1,1,:]                                                             
    Out[50]: array([16, 17, 18, 19])
    

    它还可以推广到 1d(这就像索引列表),甚至是 0d。

    如果我从这个数组中创建一个数据帧,那么该帧的数据或值就是数组本身:

    In [52]: df = pd.DataFrame(nparr)                                               
    In [53]: df                                                                     
    Out[53]: 
       0  1
    0  1  5
    1  2  6
    2  3  7
    In [54]: df._values                                                             
    Out[54]: 
    array([[1, 5],
           [2, 6],
           [3, 7]])
    

    如果我修改数组的一个元素,我们也会看到帧的变化:

    In [56]: nparr[0,1] *=100                                                       
    In [57]: nparr                                                                  
    Out[57]: 
    array([[  1, 500],
           [  2,   6],
           [  3,   7]])
    In [58]: df                                                                     
    Out[58]: 
       0    1
    0  1  500
    1  2    6
    2  3    7
    
    In [61]: df[1]          # a Series                                                        
    Out[61]: 
    0    500
    1      6
    2      7
    Name: 1, dtype: int64
    

    pandas 已将自己的索引层(包括列和行标签)添加到底层数组。它将以一种或另一种方式将其索引输入映射到数组的。

    由于还有其他构建数据帧的方法,因此帧和数组之间并不总是一对一的匹配。

    【讨论】:

    • 虽然我非常感谢您回答中的大部分信息,但我无法理解这如何解决我的问题。可能是我错过了正确理解答案所在的行。这句话的答案是:由于还有其他构造数据帧的方法,所以帧和数组之间并不总是一对一的匹配。 ?
    • 我的主要意图是表明numpy 行/列顺序只是其一般多维索引的一个实例。 pandas 设计师,无论出于何种原因,选择了系列/列方向,即使底层数据结构是一个 numpy 数组,他们也会使用它。我们大多数人只能通过辨别模式来回答为什么的问题,而不是通过阅读设计师的意图。
    • 谢谢。您的回答here 也帮助我更好地理解,尤其是您首先显示使用字段名称索引的numpy 数组的部分,类似于pandas,给出类似于pandas 系列的列输出。
    猜你喜欢
    • 1970-01-01
    • 2015-10-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-09-30
    • 1970-01-01
    • 2012-05-12
    • 2017-08-29
    相关资源
    最近更新 更多