Pandas 2.2 中文官方教程和指南(二十五·二)(4)

简介: Pandas 2.2 中文官方教程和指南(二十五·二)

Pandas 2.2 中文官方教程和指南(二十五·二)(3)https://developer.aliyun.com/article/1509411

你可以通过将 driver 参数传递给 PyTables 来在内存中创建或加载 HDFStore。只有在关闭 HDFStore 时才会将更改写入磁盘。

In [211]: store = pd.HDFStore("test.h5", "w", driver="H5FD_CORE")
In [212]: df = pd.DataFrame(np.random.randn(8, 3))
In [213]: store["test"] = df
# only after closing the store, data is written to disk:
In [214]: store.close() 
```### 二进制文件
pandas 可以轻松接受 NumPy 记录数组,如果你需要读取由 C 结构数组组成的二进制文件。例如,给定一个名为 `main.c` 的 C 程序,在 64 位机器上使用 `gcc main.c -std=gnu99` 编译,
```py
#include  <stdio.h>
#include  <stdint.h>
typedef  struct  _Data
{
  int32_t  count;
  double  avg;
  float  scale;
}  Data;
int  main(int  argc,  const  char  *argv[])
{
  size_t  n  =  10;
  Data  d[n];
  for  (int  i  =  0;  i  <  n;  ++i)
  {
  d[i].count  =  i;
  d[i].avg  =  i  +  1.0;
  d[i].scale  =  (float)  i  +  2.0f;
  }
  FILE  *file  =  fopen("binary.dat",  "wb");
  fwrite(&d,  sizeof(Data),  n,  file);
  fclose(file);
  return  0;
} 

以下 Python 代码将把二进制文件 'binary.dat' 读入 pandas 的 DataFrame,其中结构的每个元素对应于框架中的一列:

names = "count", "avg", "scale"
# note that the offsets are larger than the size of the type because of
# struct padding
offsets = 0, 8, 16
formats = "i4", "f8", "f4"
dt = np.dtype({"names": names, "offsets": offsets, "formats": formats}, align=True)
df = pd.DataFrame(np.fromfile("binary.dat", dt)) 

注意

结构元素的偏移量可能会因文件创建时所用机器的架构而异。不建议使用这种原始二进制文件格式进行通用数据存储,因为它不跨平台。我们建议使用 HDF5 或 parquet,这两种格式都受到 pandas 的 IO 功能支持。### CSV

CSV 文档

read_csv 演示

追加到 csv

逐块读取 csv

逐块读取 csv 中的特定行

读取框架的前几行

读取已压缩但不是由 gzip/bz2read_csv 理解的原生压缩格式)压缩的文件。此示例展示了一个 WinZipped 文件,但是是在上下文管理器中打开文件并使用该句柄进行读取的一般应用。点击这里查看

从文件推断数据类型

处理错误行 GH 2886

写入具有多行索引的 CSV,避免写入重复行

读取多个文件以创建单个 DataFrame

将多个文件合并为单个 DataFrame 的最佳方法是逐个读取各个框架,将所有单独的框架放入列表中,然后使用 pd.concat() 组合列表中的框架:

In [189]: for i in range(3):
 .....:    data = pd.DataFrame(np.random.randn(10, 4))
 .....:    data.to_csv("file_{}.csv".format(i))
 .....: 
In [190]: files = ["file_0.csv", "file_1.csv", "file_2.csv"]
In [191]: result = pd.concat([pd.read_csv(f) for f in files], ignore_index=True) 

您可以使用相同的方法来读取所有匹配模式的文件。以下是使用 glob 的示例:

In [192]: import glob
In [193]: import os
In [194]: files = glob.glob("file_*.csv")
In [195]: result = pd.concat([pd.read_csv(f) for f in files], ignore_index=True) 

最后,这种策略将适用于 io 文档 中描述的其他 pd.read_*(...) 函数。

解析多列中的日期组件

使用格式解析多列中的日期组件更快

In [196]: i = pd.date_range("20000101", periods=10000)
In [197]: df = pd.DataFrame({"year": i.year, "month": i.month, "day": i.day})
In [198]: df.head()
Out[198]: 
 year  month  day
0  2000      1    1
1  2000      1    2
2  2000      1    3
3  2000      1    4
4  2000      1    5
In [199]: %timeit pd.to_datetime(df.year * 10000 + df.month * 100 + df.day, format='%Y%m%d')
 .....: ds = df.apply(lambda x: "%04d%02d%02d" % (x["year"], x["month"], x["day"]), axis=1)
 .....: ds.head()
 .....: %timeit pd.to_datetime(ds)
 .....: 
4.01 ms +- 635 us per loop (mean +- std. dev. of 7 runs, 100 loops each)
1.05 ms +- 7.39 us per loop (mean +- std. dev. of 7 runs, 1,000 loops each) 
在标题和数据之间跳过行
In [200]: data = """;;;;
 .....: ;;;;
 .....: ;;;;
 .....: ;;;;
 .....: ;;;;
 .....: ;;;;
 .....: ;;;;
 .....: ;;;;
 .....: ;;;;
 .....: ;;;;
 .....: date;Param1;Param2;Param4;Param5
 .....:    ;m²;°C;m²;m
 .....: ;;;;
 .....: 01.01.1990 00:00;1;1;2;3
 .....: 01.01.1990 01:00;5;3;4;5
 .....: 01.01.1990 02:00;9;5;6;7
 .....: 01.01.1990 03:00;13;7;8;9
 .....: 01.01.1990 04:00;17;9;10;11
 .....: 01.01.1990 05:00;21;11;12;13
 .....: """
 .....: 
选项 1:显式传递要跳过的行数
In [201]: from io import StringIO
In [202]: pd.read_csv(
 .....:    StringIO(data),
 .....:    sep=";",
 .....:    skiprows=[11, 12],
 .....:    index_col=0,
 .....:    parse_dates=True,
 .....:    header=10,
 .....: )
 .....: 
Out[202]: 
 Param1  Param2  Param4  Param5
date 
1990-01-01 00:00:00       1       1       2       3
1990-01-01 01:00:00       5       3       4       5
1990-01-01 02:00:00       9       5       6       7
1990-01-01 03:00:00      13       7       8       9
1990-01-01 04:00:00      17       9      10      11
1990-01-01 05:00:00      21      11      12      13 
选项 2:先读取列名,然后读取数据
In [203]: pd.read_csv(StringIO(data), sep=";", header=10, nrows=10).columns
Out[203]: Index(['date', 'Param1', 'Param2', 'Param4', 'Param5'], dtype='object')
In [204]: columns = pd.read_csv(StringIO(data), sep=";", header=10, nrows=10).columns
In [205]: pd.read_csv(
 .....:    StringIO(data), sep=";", index_col=0, header=12, parse_dates=True, names=columns
 .....: )
 .....: 
Out[205]: 
 Param1  Param2  Param4  Param5
date 
1990-01-01 00:00:00       1       1       2       3
1990-01-01 01:00:00       5       3       4       5
1990-01-01 02:00:00       9       5       6       7
1990-01-01 03:00:00      13       7       8       9
1990-01-01 04:00:00      17       9      10      11
1990-01-01 05:00:00      21      11      12      13 
读取多个文件以创建单个 DataFrame

将多个文件合并为单个 DataFrame 的最佳方法是逐个读取各个框架,将所有单独的框架放入列表中,然后使用 pd.concat() 组合列表中的框架:

In [189]: for i in range(3):
 .....:    data = pd.DataFrame(np.random.randn(10, 4))
 .....:    data.to_csv("file_{}.csv".format(i))
 .....: 
In [190]: files = ["file_0.csv", "file_1.csv", "file_2.csv"]
In [191]: result = pd.concat([pd.read_csv(f) for f in files], ignore_index=True) 

您可以使用相同的方法来读取所有匹配模式的文件。以下是使用 glob 的示例:

In [192]: import glob
In [193]: import os
In [194]: files = glob.glob("file_*.csv")
In [195]: result = pd.concat([pd.read_csv(f) for f in files], ignore_index=True) 

最后,这种策略将适用于 io 文档 中描述的其他 pd.read_*(...) 函数。

解析多列中的日期组件

在多列中解析日期组件时,使用格式更快

In [196]: i = pd.date_range("20000101", periods=10000)
In [197]: df = pd.DataFrame({"year": i.year, "month": i.month, "day": i.day})
In [198]: df.head()
Out[198]: 
 year  month  day
0  2000      1    1
1  2000      1    2
2  2000      1    3
3  2000      1    4
4  2000      1    5
In [199]: %timeit pd.to_datetime(df.year * 10000 + df.month * 100 + df.day, format='%Y%m%d')
 .....: ds = df.apply(lambda x: "%04d%02d%02d" % (x["year"], x["month"], x["day"]), axis=1)
 .....: ds.head()
 .....: %timeit pd.to_datetime(ds)
 .....: 
4.01 ms +- 635 us per loop (mean +- std. dev. of 7 runs, 100 loops each)
1.05 ms +- 7.39 us per loop (mean +- std. dev. of 7 runs, 1,000 loops each) 
在标题和数据之间跳过行
In [200]: data = """;;;;
 .....: ;;;;
 .....: ;;;;
 .....: ;;;;
 .....: ;;;;
 .....: ;;;;
 .....: ;;;;
 .....: ;;;;
 .....: ;;;;
 .....: ;;;;
 .....: date;Param1;Param2;Param4;Param5
 .....:    ;m²;°C;m²;m
 .....: ;;;;
 .....: 01.01.1990 00:00;1;1;2;3
 .....: 01.01.1990 01:00;5;3;4;5
 .....: 01.01.1990 02:00;9;5;6;7
 .....: 01.01.1990 03:00;13;7;8;9
 .....: 01.01.1990 04:00;17;9;10;11
 .....: 01.01.1990 05:00;21;11;12;13
 .....: """
 .....: 
选项 1:显式传递行以跳过行
In [201]: from io import StringIO
In [202]: pd.read_csv(
 .....:    StringIO(data),
 .....:    sep=";",
 .....:    skiprows=[11, 12],
 .....:    index_col=0,
 .....:    parse_dates=True,
 .....:    header=10,
 .....: )
 .....: 
Out[202]: 
 Param1  Param2  Param4  Param5
date 
1990-01-01 00:00:00       1       1       2       3
1990-01-01 01:00:00       5       3       4       5
1990-01-01 02:00:00       9       5       6       7
1990-01-01 03:00:00      13       7       8       9
1990-01-01 04:00:00      17       9      10      11
1990-01-01 05:00:00      21      11      12      13 
选项 2:先读取列名,然后读取数据
In [203]: pd.read_csv(StringIO(data), sep=";", header=10, nrows=10).columns
Out[203]: Index(['date', 'Param1', 'Param2', 'Param4', 'Param5'], dtype='object')
In [204]: columns = pd.read_csv(StringIO(data), sep=";", header=10, nrows=10).columns
In [205]: pd.read_csv(
 .....:    StringIO(data), sep=";", index_col=0, header=12, parse_dates=True, names=columns
 .....: )
 .....: 
Out[205]: 
 Param1  Param2  Param4  Param5
date 
1990-01-01 00:00:00       1       1       2       3
1990-01-01 01:00:00       5       3       4       5
1990-01-01 02:00:00       9       5       6       7
1990-01-01 03:00:00      13       7       8       9
1990-01-01 04:00:00      17       9      10      11
1990-01-01 05:00:00      21      11      12      13 
选项 1:显式传递行以跳过行
In [201]: from io import StringIO
In [202]: pd.read_csv(
 .....:    StringIO(data),
 .....:    sep=";",
 .....:    skiprows=[11, 12],
 .....:    index_col=0,
 .....:    parse_dates=True,
 .....:    header=10,
 .....: )
 .....: 
Out[202]: 
 Param1  Param2  Param4  Param5
date 
1990-01-01 00:00:00       1       1       2       3
1990-01-01 01:00:00       5       3       4       5
1990-01-01 02:00:00       9       5       6       7
1990-01-01 03:00:00      13       7       8       9
1990-01-01 04:00:00      17       9      10      11
1990-01-01 05:00:00      21      11      12      13 
选项 2:先读取列名,然后读取数据
In [203]: pd.read_csv(StringIO(data), sep=";", header=10, nrows=10).columns
Out[203]: Index(['date', 'Param1', 'Param2', 'Param4', 'Param5'], dtype='object')
In [204]: columns = pd.read_csv(StringIO(data), sep=";", header=10, nrows=10).columns
In [205]: pd.read_csv(
 .....:    StringIO(data), sep=";", index_col=0, header=12, parse_dates=True, names=columns
 .....: )
 .....: 
Out[205]: 
 Param1  Param2  Param4  Param5
date 
1990-01-01 00:00:00       1       1       2       3
1990-01-01 01:00:00       5       3       4       5
1990-01-01 02:00:00       9       5       6       7
1990-01-01 03:00:00      13       7       8       9
1990-01-01 04:00:00      17       9      10      11
1990-01-01 05:00:00      21      11      12      13 

SQL

SQL 文档

使用 SQL 从数据库中读取数据

Excel

Excel 文档

从类文件句柄读取

修改 XlsxWriter 输出中的格式

仅加载可见工作表 GH 19842#issuecomment-892150745

HTML

从无法处理默认请求头的服务器读取 HTML 表格

HDFStore

HDFStores 文档

使用时间戳索引进行简单查询

使用链接的多表层次结构管理异构数据 GH 3032

合并具有数百万行的磁盘上的表

在多个进程/线程从多个进程/线程写入存储时避免不一致性

通过块对大型存储进行去重,本质上是一个递归减少操作。展示了一个从 csv 文件中接收数据并按块创建存储的函数,同时也进行了日期解析。点击这里查看

从 csv 文件逐块创建存储

在创建唯一索引的同时向存储追加数据

大数据工作流

读取一系列文件,然后在追加时为存储提供全局唯一索引

在具有低组密度的 HDFStore 上进行分组

在具有高组密度的 HDFStore 上进行分组

在 HDFStore 上进行分层查询

使用 HDFStore 进行计数

解决 HDFStore 异常

使用字符串设置 min_itemsize

使用 ptrepack 在存储上创建完全排序的索引

将属性存储到组节点

In [206]: df = pd.DataFrame(np.random.randn(8, 3))
In [207]: store = pd.HDFStore("test.h5")
In [208]: store.put("df", df)
# you can store an arbitrary Python object via pickle
In [209]: store.get_storer("df").attrs.my_attribute = {"A": 10}
In [210]: store.get_storer("df").attrs.my_attribute
Out[210]: {'A': 10} 

通过将 driver 参数传递给 PyTables,可以在内存中创建或加载 HDFStore。只有在关闭 HDFStore 时才会将更改写入磁盘。

In [211]: store = pd.HDFStore("test.h5", "w", driver="H5FD_CORE")
In [212]: df = pd.DataFrame(np.random.randn(8, 3))
In [213]: store["test"] = df
# only after closing the store, data is written to disk:
In [214]: store.close() 

二进制文件

如果需要读取由 C 结构数组组成的二进制文件,pandas 可以轻松接受 NumPy 记录数组。例如,给定一个名为 main.c 的文件中的 C 程序,在 64 位机器上使用 gcc main.c -std=gnu99 编译,

#include  <stdio.h>
#include  <stdint.h>
typedef  struct  _Data
{
  int32_t  count;
  double  avg;
  float  scale;
}  Data;
int  main(int  argc,  const  char  *argv[])
{
  size_t  n  =  10;
  Data  d[n];
  for  (int  i  =  0;  i  <  n;  ++i)
  {
  d[i].count  =  i;
  d[i].avg  =  i  +  1.0;
  d[i].scale  =  (float)  i  +  2.0f;
  }
  FILE  *file  =  fopen("binary.dat",  "wb");
  fwrite(&d,  sizeof(Data),  n,  file);
  fclose(file);
  return  0;
} 

以下 Python 代码将二进制文件 'binary.dat' 读入 pandas 的 DataFrame 中,结构的每个元素对应帧中的一列:

names = "count", "avg", "scale"
# note that the offsets are larger than the size of the type because of
# struct padding
offsets = 0, 8, 16
formats = "i4", "f8", "f4"
dt = np.dtype({"names": names, "offsets": offsets, "formats": formats}, align=True)
df = pd.DataFrame(np.fromfile("binary.dat", dt)) 

注意

结构元素的偏移量可能因创建文件的机器架构而异。不建议使用这种原始二进制文件格式进行通用数据存储,因为它不跨平台。我们建议使用 HDF5 或 parquet,这两者都受到 pandas IO 设施的支持。

计算

时间序列的数值积分(基于样本)

相关性

通常,从 DataFrame.corr() 计算的相关矩阵的下三角形式(或上三角形式)是很有用的。可以通过向 where 传递布尔掩码来实现如下:

In [215]: df = pd.DataFrame(np.random.random(size=(100, 5)))
In [216]: corr_mat = df.corr()
In [217]: mask = np.tril(np.ones_like(corr_mat, dtype=np.bool_), k=-1)
In [218]: corr_mat.where(mask)
Out[218]: 
 0         1         2        3   4
0       NaN       NaN       NaN      NaN NaN
1 -0.079861       NaN       NaN      NaN NaN
2 -0.236573  0.183801       NaN      NaN NaN
3 -0.013795 -0.051975  0.037235      NaN NaN
4 -0.031974  0.118342 -0.073499 -0.02063 NaN 

DataFrame.corr 中的 method 参数除了命名的相关性类型外还可以接受可调用对象。在这里,我们为 DataFrame 对象计算 距离相关性 矩阵。

In [219]: def distcorr(x, y):
 .....:    n = len(x)
 .....:    a = np.zeros(shape=(n, n))
 .....:    b = np.zeros(shape=(n, n))
 .....:    for i in range(n):
 .....:        for j in range(i + 1, n):
 .....:            a[i, j] = abs(x[i] - x[j])
 .....:            b[i, j] = abs(y[i] - y[j])
 .....:    a += a.T
 .....:    b += b.T
 .....:    a_bar = np.vstack([np.nanmean(a, axis=0)] * n)
 .....:    b_bar = np.vstack([np.nanmean(b, axis=0)] * n)
 .....:    A = a - a_bar - a_bar.T + np.full(shape=(n, n), fill_value=a_bar.mean())
 .....:    B = b - b_bar - b_bar.T + np.full(shape=(n, n), fill_value=b_bar.mean())
 .....:    cov_ab = np.sqrt(np.nansum(A * B)) / n
 .....:    std_a = np.sqrt(np.sqrt(np.nansum(A ** 2)) / n)
 .....:    std_b = np.sqrt(np.sqrt(np.nansum(B ** 2)) / n)
 .....:    return cov_ab / std_a / std_b
 .....: 
In [220]: df = pd.DataFrame(np.random.normal(size=(100, 3)))
In [221]: df.corr(method=distcorr)
Out[221]: 
 0         1         2
0  1.000000  0.197613  0.216328
1  0.197613  1.000000  0.208749
2  0.216328  0.208749  1.000000 

相关性

通常,从 DataFrame.corr() 计算的相关矩阵的下三角形式(或上三角形式)是很有用的。可以通过向 where 传递布尔掩码来实现如下:

In [215]: df = pd.DataFrame(np.random.random(size=(100, 5)))
In [216]: corr_mat = df.corr()
In [217]: mask = np.tril(np.ones_like(corr_mat, dtype=np.bool_), k=-1)
In [218]: corr_mat.where(mask)
Out[218]: 
 0         1         2        3   4
0       NaN       NaN       NaN      NaN NaN
1 -0.079861       NaN       NaN      NaN NaN
2 -0.236573  0.183801       NaN      NaN NaN
3 -0.013795 -0.051975  0.037235      NaN NaN
4 -0.031974  0.118342 -0.073499 -0.02063 NaN 

DataFrame.corr 中的 method 参数除了命名的相关性类型外还可以接受可调用对象。在这里,我们为 DataFrame 对象计算 距离相关性 矩阵。

In [219]: def distcorr(x, y):
 .....:    n = len(x)
 .....:    a = np.zeros(shape=(n, n))
 .....:    b = np.zeros(shape=(n, n))
 .....:    for i in range(n):
 .....:        for j in range(i + 1, n):
 .....:            a[i, j] = abs(x[i] - x[j])
 .....:            b[i, j] = abs(y[i] - y[j])
 .....:    a += a.T
 .....:    b += b.T
 .....:    a_bar = np.vstack([np.nanmean(a, axis=0)] * n)
 .....:    b_bar = np.vstack([np.nanmean(b, axis=0)] * n)
 .....:    A = a - a_bar - a_bar.T + np.full(shape=(n, n), fill_value=a_bar.mean())
 .....:    B = b - b_bar - b_bar.T + np.full(shape=(n, n), fill_value=b_bar.mean())
 .....:    cov_ab = np.sqrt(np.nansum(A * B)) / n
 .....:    std_a = np.sqrt(np.sqrt(np.nansum(A ** 2)) / n)
 .....:    std_b = np.sqrt(np.sqrt(np.nansum(B ** 2)) / n)
 .....:    return cov_ab / std_a / std_b
 .....: 
In [220]: df = pd.DataFrame(np.random.normal(size=(100, 3)))
In [221]: df.corr(method=distcorr)
Out[221]: 
 0         1         2
0  1.000000  0.197613  0.216328
1  0.197613  1.000000  0.208749
2  0.216328  0.208749  1.000000 

时间增量

时间增量 文档。

使用时间差

In [222]: import datetime
In [223]: s = pd.Series(pd.date_range("2012-1-1", periods=3, freq="D"))
In [224]: s - s.max()
Out[224]: 
0   -2 days
1   -1 days
2    0 days
dtype: timedelta64[ns]
In [225]: s.max() - s
Out[225]: 
0   2 days
1   1 days
2   0 days
dtype: timedelta64[ns]
In [226]: s - datetime.datetime(2011, 1, 1, 3, 5)
Out[226]: 
0   364 days 20:55:00
1   365 days 20:55:00
2   366 days 20:55:00
dtype: timedelta64[ns]
In [227]: s + datetime.timedelta(minutes=5)
Out[227]: 
0   2012-01-01 00:05:00
1   2012-01-02 00:05:00
2   2012-01-03 00:05:00
dtype: datetime64[ns]
In [228]: datetime.datetime(2011, 1, 1, 3, 5) - s
Out[228]: 
0   -365 days +03:05:00
1   -366 days +03:05:00
2   -367 days +03:05:00
dtype: timedelta64[ns]
In [229]: datetime.timedelta(minutes=5) + s
Out[229]: 
0   2012-01-01 00:05:00
1   2012-01-02 00:05:00
2   2012-01-03 00:05:00
dtype: datetime64[ns] 

添加和减去时间差和日期

In [230]: deltas = pd.Series([datetime.timedelta(days=i) for i in range(3)])
In [231]: df = pd.DataFrame({"A": s, "B": deltas})
In [232]: df
Out[232]: 
 A      B
0 2012-01-01 0 days
1 2012-01-02 1 days
2 2012-01-03 2 days
In [233]: df["New Dates"] = df["A"] + df["B"]
In [234]: df["Delta"] = df["A"] - df["New Dates"]
In [235]: df
Out[235]: 
 A      B  New Dates   Delta
0 2012-01-01 0 days 2012-01-01  0 days
1 2012-01-02 1 days 2012-01-03 -1 days
2 2012-01-03 2 days 2012-01-05 -2 days
In [236]: df.dtypes
Out[236]: 
A             datetime64[ns]
B            timedelta64[ns]
New Dates     datetime64[ns]
Delta        timedelta64[ns]
dtype: object 

另一个示例

可以使用 np.nan 将值设置为 NaT,类似于 datetime

In [237]: y = s - s.shift()
In [238]: y
Out[238]: 
0      NaT
1   1 days
2   1 days
dtype: timedelta64[ns]
In [239]: y[1] = np.nan
In [240]: y
Out[240]: 
0      NaT
1      NaT
2   1 days
dtype: timedelta64[ns] 

创建示例数据

要从给定值的每个组合创建数据框,类似于 R 的expand.grid()函数,我们可以创建一个字典,其中键是列名,值是数据值的列表:

In [241]: def expand_grid(data_dict):
 .....:    rows = itertools.product(*data_dict.values())
 .....:    return pd.DataFrame.from_records(rows, columns=data_dict.keys())
 .....: 
In [242]: df = expand_grid(
 .....:    {"height": [60, 70], "weight": [100, 140, 180], "sex": ["Male", "Female"]}
 .....: )
 .....: 
In [243]: df
Out[243]: 
 height  weight     sex
0       60     100    Male
1       60     100  Female
2       60     140    Male
3       60     140  Female
4       60     180    Male
5       60     180  Female
6       70     100    Male
7       70     100  Female
8       70     140    Male
9       70     140  Female
10      70     180    Male
11      70     180  Female 

恒定系列

要评估一个系列是否具有恒定值,我们可以检查series.nunique() <= 1。然而,一种更高效的方法,不需要首先计算所有唯一值,是:

In [244]: v = s.to_numpy()
In [245]: is_constant = v.shape[0] == 0 or (s[0] == s).all() 

此方法假定系列不包含缺失值。对于我们将删除 NA 值的情况,我们可以先简单地删除这些值:

In [246]: v = s.dropna().to_numpy()
In [247]: is_constant = v.shape[0] == 0 or (s[0] == s).all() 

如果缺失值被视为与任何其他值不同,则可以使用:

In [248]: v = s.to_numpy()
In [249]: is_constant = v.shape[0] == 0 or (s[0] == s).all() or not pd.notna(v).any() 

(请注意,此示例不区分np.nanpd.NANone之间的差异)

相关文章
|
12天前
|
索引 Python
Pandas 2.2 中文官方教程和指南(一)(4)
Pandas 2.2 中文官方教程和指南(一)
17 0
|
12天前
|
存储 SQL JSON
Pandas 2.2 中文官方教程和指南(一)(3)
Pandas 2.2 中文官方教程和指南(一)
23 0
|
12天前
|
XML 关系型数据库 PostgreSQL
Pandas 2.2 中文官方教程和指南(一)(2)
Pandas 2.2 中文官方教程和指南(一)
17 0
|
12天前
|
XML 关系型数据库 MySQL
Pandas 2.2 中文官方教程和指南(一)(1)
Pandas 2.2 中文官方教程和指南(一)
13 0
|
12天前
|
C++ 索引 Python
Pandas 2.2 中文官方教程和指南(五)(4)
Pandas 2.2 中文官方教程和指南(五)
16 0
|
12天前
|
索引 Python
Pandas 2.2 中文官方教程和指南(五)(3)
Pandas 2.2 中文官方教程和指南(五)
17 0
|
12天前
|
SQL API 数据格式
Pandas 2.2 中文官方教程和指南(五)(2)
Pandas 2.2 中文官方教程和指南(五)
17 0
|
12天前
|
SQL API 数据格式
Pandas 2.2 中文官方教程和指南(五)(1)
Pandas 2.2 中文官方教程和指南(五)
26 0
|
13天前
|
索引 Python
Pandas 2.2 中文官方教程和指南(四)(4)
Pandas 2.2 中文官方教程和指南(四)
16 0
|
13天前
|
存储 SQL 索引
Pandas 2.2 中文官方教程和指南(十一·二)(4)
Pandas 2.2 中文官方教程和指南(十一·二)
21 1

相关实验场景

更多