当前位置: 首页 > 面试题库 >

pandas数据框视图vs复制,我怎么知道?

昌学
2023-03-14
问题内容

之间有什么区别:

大熊猫 df.loc[:,('col_a','col_b')]

df.loc[:,['col_a','col_b']]

下面的链接虽然有效,但并未提及后者。都拉一个视图吗?第一个拉视图,第二个拉视图吗?喜欢学习熊猫。

http://pandas.pydata.org/pandas-docs/stable/indexing.html#indexing-view-
versus-copy

谢谢


问题答案:

如果您的DataFrame具有简单的列索引,则没有区别。例如,

In [8]: df = pd.DataFrame(np.arange(12).reshape(4,3), columns=list('ABC'))

In [9]: df.loc[:, ['A','B']]
Out[9]: 
   A   B
0  0   1
1  3   4
2  6   7
3  9  10

In [10]: df.loc[:, ('A','B')]
Out[10]: 
   A   B
0  0   1
1  3   4
2  6   7
3  9  10

但是,如果DataFrame具有MultiIndex,则可能会有很大的不同:

df = pd.DataFrame(np.random.randint(10, size=(5,4)),
                  columns=pd.MultiIndex.from_arrays([['foo']*2+['bar']*2,
                                                     list('ABAB')]),
                  index=pd.MultiIndex.from_arrays([['baz']*2+['qux']*3,
                                                   list('CDCDC')]))

#       foo    bar   
#         A  B   A  B
# baz C   7  9   9  9
#     D   7  5   5  4
# qux C   5  0   5  1
#     D   1  7   7  4
#     C   6  4   3  5

In [27]: df.loc[:, ('foo','B')]
Out[27]: 
baz  C    9
     D    5
qux  C    0
     D    7
     C    4
Name: (foo, B), dtype: int64

In [28]: df.loc[:, ['foo','B']]
KeyError: 'MultiIndex Slicing requires the index to be fully lexsorted tuple len (1), lexsort depth (0)'

KeyError表示必须对MultiIndex进行排序。如果我们这样做,那么我们仍然会得到不同的结果:

In [29]: df.sortlevel(axis=1).loc[:, ('foo','B')]
Out[29]: 
baz  C    9
     D    5
qux  C    0
     D    7
     C    4
Name: (foo, B), dtype: int64

In [30]: df.sortlevel(axis=1).loc[:, ['foo','B']]
Out[30]: 
      foo   
        A  B
baz C   7  9
    D   7  5
qux C   5  0
    D   1  7
    C   6  4

这是为什么?df.sortlevel(axis=1).loc[:, ('foo','B')]正在选择第一列级别等于foo,第二列级别等于的列B

相反,df.sortlevel(axis=1).loc[:, ['foo','B']]正在选择第一列级别为foo或的列B。关于第一列级别,没有B列,但是有两foo列。

我认为Pandas的操作原理是,如果您将其df.loc[...]用作 表达式
,则应假定df.loc可能正在返回副本或视图。Pandas文档未指定您应该遵循的任何规则。但是,如果您 分配 表格

df.loc[...] = value

那么您可以信任熊猫来改变df自己。

该文档之所以警告有关视图和副本之间的区别的原因,是为了使您意识到使用以下形式的链分配的陷阱

df.loc[...][...] = value

在这里,Pandasdf.loc[...]首先评估,它可以是视图或副本。现在,如果它是副本,则

df.loc[...][...] = value

正在更改的某些部分的副本df,因此对其df自身没有影响。更糟的是,由于没有引用副本,因此对副本的影响也会丢失,因此在赋值语句完成后就无法访问副本,因此(至少在CPython中)垃圾收集。

我不知道一种实用 的先验 方法来确定是否df.loc[...]要返回视图或副本。

但是,有一些经验法则可能有助于指导您的直觉(但是请注意,我们在这里讨论实现细节,因此不能保证熊猫将来会以这种方式行事):

  • 如果结果NDFrame无法表示为基础NumPy数组的基本切片,则它可能是一个副本。因此,选择任意的行或列将导致复制。选择顺序行和/或顺序列(可以表示为切片)可以返回视图。
  • 如果结果NDFrame具有不同dtypes的列,则df.loc 可能会再次返回一个副本。

然而,有一个简单的方法来确定是否x = df.loc[..]是一个视图 一个postiori
:只需看看是否改变值x影响df。如果是,则为视图,否则x为副本。



 类似资料:
  • 问题内容: 如果数据如下所示: 我想复制IsHoliday等于TRUE的行,我可以这样做: 但是是否有更好的方法来执行此操作,因为我需要将假日行重复5次,如果使用上述方法,则必须追加5次。 问题答案: 您可以放入列表中,然后执行以下操作:

  • 轻推电脑端消息框可实现图片复制。 操作方法:右击消息框中的图片,选择复制。

  • 问题内容: 这是我的数据框,应重复5次: 我想要这样的结果: 但是必须有一种比保持追加更聪明的方法。实际上,Im正在处理的数据帧应重复50次。 我还没有发现任何实用的东西,包括类似-—的东西,但它在数据框架上不起作用。 有人可以帮忙吗? 问题答案: 您可以使用以下功能: 如果只想重复值而不是索引,则可以执行以下操作:

  • 问题内容: 我有一个访问前端和sql server后端。我想知道哪些用户当前正在使用该数据库。使用access或sql-server可以做到这一点吗? 问题答案: 在SQL Server中,您可以运行以下存储过程: 编辑: 如果要在任何给定时间查看谁在使用服务器,可以使用此查询。这将使您可以随意进一步过滤。

  • 问题内容: 当从父数据帧中选择子数据帧时,我注意到有些程序员使用该方法复制数据帧。例如, …而不只是 他们为什么要复制数据框?如果我不复制怎么办? 问题答案: 这扩展了保罗的答案。在Pandas中,为DataFrame编制索引将返回对初始DataFrame的引用。因此,更改子集将更改初始DataFrame。因此,如果要确保不更改初始DataFrame,则需要使用该副本。考虑以下代码: 你会得到:

  • 问题内容: 我似乎找不到有关Redis命令的有用信息。我想知道给定键值的数据类型。例如,要列出数据库的所有键,我运行以下命令: 在我的设置中,得到以下结果: 我如何知道密钥包含的数据类型?我尝试运行,但出现错误 有什么想法吗? 问题答案: 您可以使用type命令:http : //redis.io/commands/type