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

如何将现有Pandas DataFrame的所有值设置为零?

邵文乐
2023-03-14
问题内容

我目前有一个带有日期索引的现有Pandas DataFrame,每个列都有一个特定的名称。

对于数据单元,它们充满了各种浮点值。

我想复制我的DataFrame,但将所有这些值替换为零。

目的是重用DataFrame的结构(尺寸,索引,列名),但通过将其替换为零来清除所有当前值。

我目前实现此目标的方式如下:

df[df > 0] = 0

但是,这不会替换DataFrame中的任何负值。

是否存在一种更通用的方法来用单个公共值填充整个现有DataFrame?

预先感谢您的帮助。


问题答案:

也可以保留的绝对最快的方法dtypes如下:

for col in df.columns:
    df[col].values[:] = 0

这将直接写入每个列的基础numpy数组。我怀疑其他任何方法都不会比这更快,因为这不会分配额外的存储空间并且不会通过熊猫的dtype处理。您也np.issubdtype可以只将数字列清零。如果您有混合的dtypeDataFrame,这可能就是您想要的,但是,如果您的DataFrame已经是完全数字的,那么这当然不是必需的。

for col in df.columns:
    if np.issubdtype(df[col].dtype, np.number):
        df[col].values[:] = 0

对于小型DataFrame,子类型检查会花费一些成本。但是,将非数字列清零的成本非常高,因此,如果不确定DataFrame是否完全为数字,则可能应包括issubdtype检查。

时序比较

设定

import pandas as pd
import html" target="_blank">numpy as np

def make_df(n, only_numeric):
    series = [
        pd.Series(range(n), name="int", dtype=int),
        pd.Series(range(n), name="float", dtype=float),
    ]
    if only_numeric:
        series.extend(
            [
                pd.Series(range(n, 2 * n), name="int2", dtype=int),
                pd.Series(range(n, 2 * n), name="float2", dtype=float),
            ]
        )
    else:
        series.extend(
            [
                pd.date_range(start="1970-1-1", freq="T", periods=n, name="dt")
                .to_series()
                .reset_index(drop=True),
                pd.Series(
                    [chr((i % 26) + 65) for i in range(n)],
                    name="string",
                    dtype="object",
                ),
            ]
        )

    return pd.concat(series, axis=1)

>>> make_df(5, True)
   int  float  int2  float2
0    0    0.0     5     5.0
1    1    1.0     6     6.0
2    2    2.0     7     7.0
3    3    3.0     8     8.0
4    4    4.0     9     9.0

>>> make_df(5, False)
   int  float                  dt string
0    0    0.0 1970-01-01 00:00:00      A
1    1    1.0 1970-01-01 00:01:00      B
2    2    2.0 1970-01-01 00:02:00      C
3    3    3.0 1970-01-01 00:03:00      D
4    4    4.0 1970-01-01 00:04:00      E

小数据框

n = 10_000

# Numeric df, no issubdtype check
%%timeit df = make_df(n, True)
for col in df.columns:
    df[col].values[:] = 0
36.1 µs ± 510 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each)

# Numeric df, yes issubdtype check
%%timeit df = make_df(n, True)
for col in df.columns:
    if np.issubdtype(df[col].dtype, np.number):
        df[col].values[:] = 0
53 µs ± 645 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each)

# Non-numeric df, no issubdtype check
%%timeit df = make_df(n, False)
for col in df.columns:
    df[col].values[:] = 0
113 µs ± 391 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each)

# Non-numeric df, yes issubdtype check
%%timeit df = make_df(n, False)
for col in df.columns:
    if np.issubdtype(df[col].dtype, np.number):
        df[col].values[:] = 0
39.4 µs ± 1.91 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)

大数据框

n = 10_000_000

# Numeric df, no issubdtype check
%%timeit df = make_df(n, True)
for col in df.columns:
    df[col].values[:] = 0
38.7 ms ± 151 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)

# Numeric df, yes issubdtype check
%%timeit df = make_df(n, True)
for col in df.columns:
    if np.issubdtype(df[col].dtype, np.number):
        df[col].values[:] = 0
39.1 ms ± 556 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)

# Non-numeric df, no issubdtype check
%%timeit df = make_df(n, False)
for col in df.columns:
    df[col].values[:] = 0
99.5 ms ± 748 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)

# Non-numeric df, yes issubdtype check
%%timeit df = make_df(n, False)
for col in df.columns:
    if np.issubdtype(df[col].dtype, np.number):
        df[col].values[:] = 0
17.8 ms ± 228 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

我之前曾建议过以下答案,但现在我认为这是有害的-它比上述答案慢得多,也很难推理。 它唯一的优点是写得更好。

最干净的方法是使用裸冒号引用整个数据框。

df[:] = 0

不幸的是,dtype情况有点模糊,因为结果数据帧中的每一列都将具有相同的值dtype。如果的每一列df都是原来的float,则新列dtypes仍然是
float。但是,如果一列是intobject,似乎新的dtypes意愿 可以int



 类似资料:
  • 问题内容: 如何在SQL表中将所有0值都设置为NULL? 提前致谢。 问题答案:

  • 如何将值中的所有位设置为1?使用AVX或AVX2的本质? 而我似乎在AVX中找不到一个简单的按位非运算?如果这是可用的,我可以简单地使用setzero,后面跟着一个向量NOT。

  • 问题内容: 我为什么要这样做: 我需要自动化一个需要客户端SSL证书的网站。我知道这是无法使用fp.set_preference()指定的选项。我无法控制要连接的服务器,因此无法更改安全设置。 我尝试了什么 我创建了一个单独的Firefox配置文件,其中设置了必需的“受客户端密码保护的SSL证书”,并自动选择了一个证书和一些手动代理设置(SOCKS 5)。经过大量谷歌搜索后,我将代码设置如下: 问

  • 我正在尝试做一些清理方法。其中我有几个字段,我想调用它们各自的清理方法,然后将它们设置为NULL。 我将所有对象添加到ArrayList中,然后将其传递给该方法: 然而,这并不起作用,我的单元测试显示,在调用此方法后,对象不为null。 如何将列表中的所有对象设置为NULL?

  • 问题内容: 我在磁盘上有一个现有文件(例如/folder/file.txt),在Django中有一个FileField模型字段。 当我做 它将文件另存为file_1.txt(下次是_2,等等)。 我知道为什么,但是我不想要这种行为-我知道我想要与该字段关联的文件确实在那里等着我,我只想让Django指向它。 问题答案: 如果要永久执行此操作,则需要创建自己的FileStorage类 现在在模型中,

  • 问题内容: 我真的很喜欢将sequelize用作我的节点应用程序的ORM,但是现在,当默认情况下在查询时它们传递DAO对象时,我有点恼火。如何始终将raw选项设置为true? 问题答案: 根据文档: 如果您不提供SQL以外的其他参数,则将raw假定为true,并且sequelize将不会尝试对查询结果进行任何格式化。 话虽如此 : Sequelize对象具有[options.query = {}]