获取数据的统计洞察#
Woodwork 在你的 DataFrames 上提供了方法,让你能够利用 Woodwork 存储的类型信息来更好地理解你的数据。
跟着学习如何在零售数据的 DataFrame 上使用 Woodwork 的统计方法,同时演示函数的全部功能。
[1]:
import numpy as np
import pandas as pd
from woodwork.demo import load_retail
df = load_retail()
df.ww
[1]:
物理类型 | 逻辑类型 | 语义标签 | |
---|---|---|---|
列 | |||
order_product_id | category | 分类 | ['index'] |
order_id | category | 分类 | ['category'] |
product_id | category | 分类 | ['category'] |
description | string | 自然语言 | [] |
quantity | int64 | 整数 | ['numeric'] |
order_date | datetime64[ns] | 日期时间 | ['time_index'] |
unit_price | float64 | 双精度浮点数 | ['numeric'] |
customer_name | category | 分类 | ['category'] |
country | category | 分类 | ['category'] |
total | float64 | 双精度浮点数 | ['numeric'] |
cancelled | bool | 布尔值 | [] |
DataFrame.ww.describe#
使用 df.ww.describe()
计算 DataFrame 中各列的统计信息,返回结果为 pandas DataFrame 格式,其中包含对每列执行的相关计算。请注意,对于 LatLong 逻辑类型,nan
和 (nan, nan)
值都会计入 nan_count
。
[2]:
df.ww.describe()
[2]:
order_id | product_id | description | quantity | order_date | unit_price | customer_name | country | total | cancelled | |
---|---|---|---|---|---|---|---|---|---|---|
physical_type | category | category | string[python] | int64 | datetime64[ns] | float64 | category | category | float64 | bool |
logical_type | 分类 | 分类 | 自然语言 | 整数 | 日期时间 | 双精度浮点数 | 分类 | 分类 | 双精度浮点数 | 布尔值 |
semantic_tags | {category} | {category} | {} | {numeric} | {time_index} | {numeric} | {category} | {category} | {numeric} | {} |
count | 401604 | 401604 | 401604 | 401604.0 | 401604 | 401604.0 | 401604 | 401604 | 401604.0 | 401604 |
nunique | 22190 | 3684 | NaN | 436.0 | 20460 | 620.0 | 4372 | 37 | 3946.0 | NaN |
nan_count | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
mean | NaN | NaN | NaN | 12.183273 | 2011-07-10 12:08:23.848567552 | 5.732205 | NaN | NaN | 34.012502 | NaN |
mode | 576339 | 85123A | WHITE HANGING HEART T-LIGHT HOLDER | 1 | 2011-11-14 15:27:00 | 2.0625 | Mary Dalton | United Kingdom | 24.75 | False |
std | NaN | NaN | NaN | 250.283037 | NaN | 115.110658 | NaN | NaN | 710.081161 | NaN |
min | NaN | NaN | NaN | -80995 | 2010-12-01 08:26:00 | 0.0 | NaN | NaN | -277974.84 | NaN |
first_quartile | NaN | NaN | NaN | 2.0 | NaN | 2.0625 | NaN | NaN | 7.0125 | NaN |
second_quartile | NaN | NaN | NaN | 5.0 | NaN | 3.2175 | NaN | NaN | 19.305 | NaN |
third_quartile | NaN | NaN | NaN | 12.0 | NaN | 6.1875 | NaN | NaN | 32.67 | NaN |
max | NaN | NaN | NaN | 80995 | 2011-12-09 12:50:00 | 64300.5 | NaN | NaN | 277974.84 | NaN |
num_true | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | 8872 |
num_false | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | 392732 |
在上面的 dataframe 中有几点需要注意
Woodwork 索引
order_product_id
未包含在内我们根据 Woodwork 的类型系统提供每列的类型信息
任何无法为列计算的统计信息,例如
num_false
应用于Datetime
列时,都填充为NaN
。除了
nunique
之外,空值不计入任何计算中。
DataFrame.ww.value_counts#
使用 df.ww.value_counts()
计算将 category
作为标准标签的每列中最频繁的值。这会返回一个字典,其中每列都关联着一个按值排序的字典列表。每个字典包含 value
和 count
。
[3]:
df.ww.value_counts()
[3]:
{'order_product_id': [{'value': 401603, 'count': 1},
{'value': 0, 'count': 1},
{'value': 1, 'count': 1},
{'value': 2, 'count': 1},
{'value': 401564, 'count': 1},
{'value': 401565, 'count': 1},
{'value': 401566, 'count': 1},
{'value': 401567, 'count': 1},
{'value': 401568, 'count': 1},
{'value': 401569, 'count': 1}],
'order_id': [{'value': '576339', 'count': 542},
{'value': '579196', 'count': 533},
{'value': '580727', 'count': 529},
{'value': '578270', 'count': 442},
{'value': '573576', 'count': 435},
{'value': '567656', 'count': 421},
{'value': '567183', 'count': 392},
{'value': '575607', 'count': 377},
{'value': '571441', 'count': 364},
{'value': '570488', 'count': 353}],
'product_id': [{'value': '85123A', 'count': 2065},
{'value': '22423', 'count': 1894},
{'value': '85099B', 'count': 1659},
{'value': '47566', 'count': 1409},
{'value': '84879', 'count': 1405},
{'value': '20725', 'count': 1346},
{'value': '22720', 'count': 1224},
{'value': 'POST', 'count': 1196},
{'value': '22197', 'count': 1110},
{'value': '23203', 'count': 1108}],
'customer_name': [{'value': 'Mary Dalton', 'count': 7812},
{'value': 'Dalton Grant', 'count': 5898},
{'value': 'Jeremy Woods', 'count': 5128},
{'value': 'Jasmine Salazar', 'count': 4459},
{'value': 'James Robinson', 'count': 2759},
{'value': 'Bryce Stewart', 'count': 2478},
{'value': 'Vanessa Sanchez', 'count': 2085},
{'value': 'Laura Church', 'count': 1853},
{'value': 'Kelly Alvarado', 'count': 1667},
{'value': 'Ashley Meyer', 'count': 1640}],
'country': [{'value': 'United Kingdom', 'count': 356728},
{'value': 'Germany', 'count': 9480},
{'value': 'France', 'count': 8475},
{'value': 'EIRE', 'count': 7475},
{'value': 'Spain', 'count': 2528},
{'value': 'Netherlands', 'count': 2371},
{'value': 'Belgium', 'count': 2069},
{'value': 'Switzerland', 'count': 1877},
{'value': 'Portugal', 'count': 1471},
{'value': 'Australia', 'count': 1258}]}
DataFrame.ww.dependence#
df.ww.dependence
计算所有相关列对之间的几种依赖性/相关性度量。某些类型(如字符串)无法计算依赖性。
列 A
和 B
之间的互信息可以理解为你了解列 B
的值时,能够获得关于列 A
的知识量。 A
和 B
之间的互信息越多,在已知 B
的情况下,A
的不确定性就越小,反之亦然。
皮尔逊相关系数衡量 A
和 B
之间的线性相关性。
[4]:
df.ww.dependence(measures="all", nrows=1000)
/home/docs/checkouts/readthedocs.org/user_builds/feature-labs-inc-datatables/envs/stable/lib/python3.9/site-packages/woodwork/statistics_utils/_get_dependence_dict.py:137: UserWarning: Dropping columns ['order_id', 'customer_name'] to allow mutual information to run faster
warnings.warn(
[4]:
column_1 | column_2 | pearson | spearman | mutual_info | max | |
---|---|---|---|---|---|---|
0 | quantity | total | 0.532443 | 0.708133 | 0.217693 | 0.708133 |
1 | quantity | unit_price | -0.128447 | -0.367468 | 0.086608 | -0.367468 |
2 | unit_price | total | 0.130113 | 0.313225 | 0.104822 | 0.313225 |
3 | quantity | cancelled | -0.141777 | -0.231845 | 0.025767 | -0.231845 |
4 | total | cancelled | -0.145310 | -0.230311 | 0.030746 | -0.230311 |
5 | product_id | unit_price | NaN | NaN | 0.142626 | 0.142626 |
6 | unit_price | cancelled | 0.051929 | 0.064367 | 0.000133 | 0.064367 |
7 | product_id | total | NaN | NaN | 0.024799 | 0.024799 |
8 | quantity | country | NaN | NaN | 0.020539 | 0.020539 |
9 | country | total | NaN | NaN | 0.016507 | 0.016507 |
10 | product_id | quantity | NaN | NaN | 0.015635 | 0.015635 |
11 | country | cancelled | NaN | NaN | 0.007489 | 0.007489 |
12 | unit_price | country | NaN | NaN | 0.002613 | 0.002613 |
13 | product_id | country | NaN | NaN | 0.001545 | 0.001545 |
14 | product_id | cancelled | NaN | NaN | -0.000172 | -0.000172 |
可用参数#
df.ww.dependence
提供了各种参数用于调整依赖性计算。
measure
- 要计算哪些依赖性度量。可以提供一个度量列表来一次性计算多个度量。有效的度量字符串:“pearson”: 计算皮尔逊相关系数
“spearman”: 计算斯皮尔曼相关系数
“mutual_info”: 计算列之间的互信息
“max”: 同时计算皮尔逊相关系数和互信息,并为每对列返回 max(abs(pearson), mutual)
“all”: 包含 “pearson”、“mutual” 和 “max” 的列
num_bins
- 为了计算连续数据的互信息,Woodwork 将数值数据分箱到不同的类别中。此参数允许你选择用于对数据进行分类的箱数。默认使用 10 个箱
箱越多,列的多样性就越大。使用的箱数应准确反映数据的分布情况。
nrows
- 如果nrows
设置的值小于 DataFrame 中的行数,则会从底层数据中随机抽样该数量的行。默认使用所有可用行。
减少行数可以加快对具有大量行的 DataFrame 计算互信息,但应注意采样数量足够大,以便准确反映数据。
include_index
- 如果设置为True
且定义了对互信息有效的逻辑类型索引,则索引列将包含在互信息输出中。默认为
False
现在你了解了参数,可以探索改变箱数。注意——这仅影响数值列 quantity
和 unit_price
。将箱数从 10 增加到 50,仅显示受影响的列。
[5]:
dep_df = df.ww.dependence(measures="all", nrows=1000)
dep_df[
dep_df["column_1"].isin(["unit_price", "quantity"])
| dep_df["column_2"].isin(["unit_price", "quantity"])
]
/home/docs/checkouts/readthedocs.org/user_builds/feature-labs-inc-datatables/envs/stable/lib/python3.9/site-packages/woodwork/statistics_utils/_get_dependence_dict.py:137: UserWarning: Dropping columns ['order_id', 'customer_name'] to allow mutual information to run faster
warnings.warn(
[5]:
column_1 | column_2 | pearson | spearman | mutual_info | max | |
---|---|---|---|---|---|---|
0 | quantity | total | 0.532443 | 0.708133 | 0.217693 | 0.708133 |
1 | quantity | unit_price | -0.128447 | -0.367468 | 0.086608 | -0.367468 |
2 | unit_price | total | 0.130113 | 0.313225 | 0.104822 | 0.313225 |
3 | quantity | cancelled | -0.141777 | -0.231845 | 0.025767 | -0.231845 |
5 | product_id | unit_price | NaN | NaN | 0.142626 | 0.142626 |
6 | unit_price | cancelled | 0.051929 | 0.064367 | 0.000133 | 0.064367 |
8 | quantity | country | NaN | NaN | 0.020539 | 0.020539 |
10 | product_id | quantity | NaN | NaN | 0.015635 | 0.015635 |
12 | unit_price | country | NaN | NaN | 0.002613 | 0.002613 |
[6]:
dep_df = df.ww.dependence(measures="all", nrows=1000, num_bins=50)
dep_df[
dep_df["column_1"].isin(["unit_price", "quantity"])
| dep_df["column_2"].isin(["unit_price", "quantity"])
]
/home/docs/checkouts/readthedocs.org/user_builds/feature-labs-inc-datatables/envs/stable/lib/python3.9/site-packages/woodwork/statistics_utils/_get_dependence_dict.py:137: UserWarning: Dropping columns ['order_id', 'customer_name'] to allow mutual information to run faster
warnings.warn(
[6]:
column_1 | column_2 | pearson | spearman | mutual_info | max | |
---|---|---|---|---|---|---|
0 | quantity | total | 0.532443 | 0.708133 | 0.338410 | 0.708133 |
1 | unit_price | total | 0.130113 | 0.313225 | 0.369177 | 0.369177 |
2 | quantity | unit_price | -0.128447 | -0.367468 | 0.105124 | -0.367468 |
3 | quantity | cancelled | -0.141777 | -0.231845 | 0.017920 | -0.231845 |
5 | product_id | unit_price | NaN | NaN | 0.163247 | 0.163247 |
6 | unit_price | cancelled | 0.051929 | 0.064367 | 0.000578 | 0.064367 |
8 | quantity | country | NaN | NaN | 0.024711 | 0.024711 |
9 | product_id | quantity | NaN | NaN | 0.019753 | 0.019753 |
12 | unit_price | country | NaN | NaN | 0.006367 | 0.006367 |
为了在互信息输出中包含索引列,运行计算时设置 include_index=True
。
[7]:
dep_df = df.ww.dependence(measures="all", nrows=1000, num_bins=50, include_index=True)
dep_df[
dep_df["column_1"].isin(["order_product_id"])
| dep_df["column_2"].isin(["order_product_id"])
]
/home/docs/checkouts/readthedocs.org/user_builds/feature-labs-inc-datatables/envs/stable/lib/python3.9/site-packages/woodwork/statistics_utils/_get_dependence_dict.py:137: UserWarning: Dropping columns ['order_id', 'customer_name'] to allow mutual information to run faster
warnings.warn(
[7]:
column_1 | column_2 | pearson | spearman | mutual_info | max | |
---|---|---|---|---|---|---|
15 | order_product_id | product_id | NaN | NaN | 2.253749e-10 | 2.253749e-10 |
16 | order_product_id | total | NaN | NaN | 2.000378e-12 | 2.000378e-12 |
17 | order_product_id | quantity | NaN | NaN | 1.125030e-12 | 1.125030e-12 |
18 | order_product_id | unit_price | NaN | NaN | 1.095753e-12 | 1.095753e-12 |
19 | order_product_id | country | NaN | NaN | 2.012074e-13 | 2.012074e-13 |
20 | order_product_id | cancelled | NaN | NaN | 1.495338e-14 | 1.495338e-14 |
使用 Series.ww.box_plot_dict 进行离群值检测#
Woodwork 进行单变量离群值检测的一种方法是 IQR(四分位距)方法。这可以使用 series.ww.box_plot_dict
方法按列进行,该方法识别离群值并包含构建箱线图所需的统计数据。
[8]:
total = df.ww["total"]
box_plot_dict = total.ww.box_plot_dict()
print("high bound: ", box_plot_dict["high_bound"])
print("low_bound: ", box_plot_dict["low_bound"])
print("quantiles: ", box_plot_dict["quantiles"])
print("number of low outliers: ", len(box_plot_dict["low_values"]))
print("number of high outliers: ", len(box_plot_dict["high_values"]))
high bound: 71.15625
low_bound: -31.47375
quantiles: {0.0: -277974.84, 0.25: 7.0124999999999975, 0.5: 19.305, 0.75: 32.669999999999995, 1.0: 277974.84}
number of low outliers: 1922
number of high outliers: 31016
我们可以看到零售数据集中的 total
列有许多离群值,并且它们更偏向于数据集的顶部。dataframe 中大约有 40 万行,因此约 8% 的值是离群值。我们再看看一个相同长度的服从正态分布的数据列,看看为其生成的统计数据是什么样子。
[9]:
rnd = np.random.RandomState(33)
s = pd.Series(rnd.normal(50, 10, 401604))
s.ww.init()
box_plot_dict = s.ww.box_plot_dict()
print("high bound: ", box_plot_dict["method"])
print("high bound: ", box_plot_dict["high_bound"])
print("low_bound: ", box_plot_dict["low_bound"])
print("quantiles: ", box_plot_dict["quantiles"])
print("number of low outliers: ", len(box_plot_dict["low_values"]))
print("number of high outliers: ", len(box_plot_dict["high_values"]))
high bound: box_plot
high bound: 77.04098
low_bound: 22.89795
quantiles: {0.0: 4.519658918840335, 0.25: 43.20158903786463, 0.5: 49.988236390934304, 0.75: 56.73734594188448, 1.0: 95.28094989391388}
number of low outliers: 1460
number of high outliers: 1381
对于正态分布的数据集,出现离群值的可能性更接近我们预期的 .7% 左右。
使用 Series.ww.medcouple_dict 进行离群值检测#
Woodwork 进行单变量离群值检测的另一种方法是通过 medcouple 统计量,通过 series.ww.medcouple_dict
实现。与 series.ww.box_plot_dict
类似,此方法也返回构建箱线图所需的信息。
[10]:
total = df.ww["total"]
medcouple_dict = total.ww.medcouple_dict()
print("medcouple: ", medcouple_dict["method"])
print("medcouple: ", medcouple_dict["medcouple_stat"])
print("high bound: ", medcouple_dict["high_bound"])
print("low_bound: ", medcouple_dict["low_bound"])
print("quantiles: ", medcouple_dict["quantiles"])
print("number of low outliers: ", len(medcouple_dict["low_values"]))
print("number of high outliers: ", len(medcouple_dict["high_values"]))
medcouple: medcouple
medcouple: 0.111
high bound: 71.40484
low_bound: -31.22676
quantiles: {0.0: -277974.84, 0.25: 7.0124999999999975, 0.5: 19.305, 0.75: 32.669999999999995, 1.0: 277974.84}
number of low outliers: 1928
number of high outliers: 31001
识别出的离群值数量已减少到约 7% 的行。此外,这些离群值的方向也发生了变化,识别出的下部离群值更多,上部离群值更少。这是因为 medcouple 统计量在确定哪些点最可能是离群值时考虑了分布的偏度。对于长尾分布,箱线图方法可能不太适用。medcouple 统计量最多基于列中 10,000 个随机抽样的观测值进行计算。此值可以在 Config
设置中通过 ww.config.set_option("medcouple_sample_size", N)
更改。
[11]:
rnd = np.random.RandomState(33)
s = pd.Series(rnd.normal(50, 10, 401604))
s.ww.init()
medcouple_dict = s.ww.medcouple_dict()
print("medcouple: ", medcouple_dict["medcouple_stat"])
print("high bound: ", medcouple_dict["high_bound"])
print("low_bound: ", medcouple_dict["low_bound"])
print("quantiles: ", medcouple_dict["quantiles"])
print("number of low outliers: ", len(medcouple_dict["low_values"]))
print("number of high outliers: ", len(medcouple_dict["high_values"]))
medcouple: -0.003
high bound: 77.04126
low_bound: 22.89823
quantiles: {0.0: 4.519658918840335, 0.25: 43.20158903786463, 0.5: 49.988236390934304, 0.75: 56.73734594188448, 1.0: 95.28094989391388}
number of low outliers: 1460
number of high outliers: 1380
如你所见,medcouple 统计量接近 0,这表明数据几乎没有偏度。当数据正常时,通过 Medcouple 统计量识别出的离群值数量与通过箱线图方法识别出的数量大致相同。
使用 Series.ww.get_outliers 进行离群值检测#
知道是使用箱线图方法还是 medcouple 方法可能会令人困惑。你可能不知道分布是否偏斜,如果是,也不知道是否偏斜得足够大以支持使用 medcouple_dict
。方法 get_outliers
可以用来解决这些问题。使用默认方法 best
运行 series.ww.get_outliers
将根据最佳方法返回离群值信息。
这是通过对序列进行随机抽样计算 medcouple 统计量来确定的。如果该抽样的 medcouple 统计量的绝对值小于默认值 0.3,则选择的方法将是箱线图。如果大于或等于 0.3,则使用 medcouple 方法(因为这表示分布中至少存在中等程度的偏度)。
要更改此默认的 medcouple 阈值 0.3,请随时通过 Config
设置中的 ww.config.set_option("medcouple_threshold", 0.5)
更改该值。
从含噪时间序列数据推断频率#
df.ww.infer_temporal_frequencies
将推断每个时间列的观测频率(每日、每两周、每年等),即使是在含噪数据上。如果一个时间列主要是一种频率,但以任何方式存在噪声(即包含重复时间戳、nan、间隙或与整体频率不符的时间戳),此表访问器方法将提供最可能的频率以及有关不符合此频率的数据行信息。
推断无噪声数据#
如果你的时间序列数据是完美的且不包含任何噪声数据,df.ww.infer_temporal_frequencies()
将返回一个字典,其中键是每个时间列的列名,值是 pandas 别名字符串。
[12]:
df = pd.DataFrame(
{
"idx": range(100),
"dt1": pd.date_range("2005-01-01", periods=100, freq="H"),
"dt2": pd.date_range("2005-01-01", periods=100, freq="B"),
}
)
df.ww.init()
df.ww.infer_temporal_frequencies()
/tmp/ipykernel_1249/2560597039.py:4: FutureWarning: 'H' is deprecated and will be removed in a future version, please use 'h' instead.
"dt1": pd.date_range("2005-01-01", periods=100, freq="H"),
[12]:
{'dt1': 'h', 'dt2': 'B'}
推断含噪声数据(缺失值)#
如果你的时间序列数据存在噪声,并且你传递了 debug=True
标志,返回的字典还将包含每个时间列的 debug 对象。此对象有助于你了解数据中存在问题的位置。
[13]:
dt1_a = pd.date_range(end="2005-01-01 10:00:00", periods=500, freq="H")
dt1_b = pd.date_range(start="2005-01-01 15:00:00", periods=500, freq="H")
df = pd.DataFrame(
{
"idx": range(1000),
"dt1": dt1_a.append(dt1_b),
}
)
df.ww.init()
infer_dict = df.ww.infer_temporal_frequencies(debug=True)
inferred_freq, debug_object = infer_dict["dt1"]
assert inferred_freq is None
debug_object
/tmp/ipykernel_1249/4098424264.py:1: FutureWarning: 'H' is deprecated and will be removed in a future version, please use 'h' instead.
dt1_a = pd.date_range(end="2005-01-01 10:00:00", periods=500, freq="H")
/tmp/ipykernel_1249/4098424264.py:2: FutureWarning: 'H' is deprecated and will be removed in a future version, please use 'h' instead.
dt1_b = pd.date_range(start="2005-01-01 15:00:00", periods=500, freq="H")
[13]:
{'actual_range_start': '2004-12-11T15:00:00',
'actual_range_end': '2005-01-22T10:00:00',
'message': None,
'estimated_freq': 'h',
'estimated_range_start': '2004-12-11T15:00:00',
'estimated_range_end': '2005-01-22T10:00:00',
'duplicate_values': [],
'missing_values': [{'dt': '2005-01-01T11:00:00', 'idx': 500, 'range': 4}],
'extra_values': [],
'nan_values': []}
在上面的例子中,我们可以看到元组的第一个元素是 None,因为时间序列有错误,无法推断。
在 debug_object
中,我们可以清楚地看到 estimated_freq
是表示每小时的 H
,还有一些额外信息,我们将在下面解释。
Debug 对象描述#
Debug 对象包含以下信息:
actual_range_start: 观测到的开始时间的 ISO 8601 格式字符串
actual_range_end: 观测到的结束时间的 ISO 8601 格式字符串
message: 描述为何无法推断频率的消息
estimated_freq: 推断出的频率
estimated_range_start: 推断的开始时间的 ISO 8601 格式字符串
estimated_range_end: 推断的结束时间的 ISO 8601 格式字符串
duplicate_values: 重复值范围对象数组(如下所述)
missing_values: 缺失值范围对象数组(如下所述)
extra_values: 额外值范围对象数组(如下所述)
nan_values: nan 值范围对象数组(如下所述)
范围对象包含以下信息:
dt: 此范围中第一个时间戳的 ISO 8601 格式字符串
idx: 此范围中第一个时间戳的索引
对于重复值和额外值,idx 是指观测数据
对于缺失值,idx 是指推断数据。
range: 此范围的长度。
通过以下示例可以最好地理解此信息
在上图所示中,你可以看到左侧是预期的时间序列,右侧是观测到的时间序列。此时间序列有以下错误:
重复值
“01:00:00” 在观测索引 1 和 2 处重复两次
缺失值
“04:00:00” 在推断索引 3 处缺失
额外值
“06:20:00” 是在观测索引 7 处的额外值
我们可以在下面的代码中重新创建这个示例。请注意,由于我们在时间序列开头填充了良好数据,索引偏移了 500。
[14]:
dt_a = pd.date_range(end="2005-01-01T00:00:00.000Z", periods=500, freq="H").to_series()
dt_b = [
"2005-01-01T01:00:00.000Z",
"2005-01-01T01:00:00.000Z",
"2005-01-01T01:00:00.000Z",
"2005-01-01T02:00:00.000Z",
"2005-01-01T03:00:00.000Z",
"2005-01-01T05:00:00.000Z",
"2005-01-01T06:00:00.000Z",
"2005-01-01T06:20:00.000Z",
"2005-01-01T07:00:00.000Z",
"2005-01-01T08:00:00.000Z",
]
dt_b = pd.Series([pd.Timestamp(d) for d in dt_b])
dt_c = pd.date_range(
start="2005-01-01T09:00:00.000Z", periods=500, freq="H"
).to_series()
dt = pd.concat([dt_a, dt_b, dt_c]).reset_index(drop=True)
dt = pd.to_datetime(dt, utc=True)
df = pd.DataFrame({"dt": dt})
df.ww.init()
df.ww.infer_temporal_frequencies(debug=True)
/tmp/ipykernel_1249/3056248247.py:1: FutureWarning: 'H' is deprecated and will be removed in a future version, please use 'h' instead.
dt_a = pd.date_range(end="2005-01-01T00:00:00.000Z", periods=500, freq="H").to_series()
/tmp/ipykernel_1249/3056248247.py:15: FutureWarning: 'H' is deprecated and will be removed in a future version, please use 'h' instead.
dt_c = pd.date_range(
[14]:
{'dt': (None,
{'actual_range_start': '2004-12-11T05:00:00',
'actual_range_end': '2005-01-22T04:00:00',
'message': None,
'estimated_freq': 'h',
'estimated_range_start': '2004-12-11T05:00:00',
'estimated_range_end': '2005-01-22T04:00:00',
'duplicate_values': [{'dt': '2005-01-01T01:00:00', 'idx': 501, 'range': 2}],
'missing_values': [{'dt': '2005-01-01T04:00:00', 'idx': 503, 'range': 1}],
'extra_values': [{'dt': '2005-01-01T06:20:00', 'idx': 507, 'range': 1}],
'nan_values': []})}