pandas自動推斷日期型別
阿新 • • 發佈:2021-01-19
構建一個csv檔案:
import pandas as pd
pd.DataFrame(data={"datetime": ["1999-10-10 10:10:10"] * 150, "index": range(150)}).to_csv('/tmp/test.csv', index=False)
檢視/tmp/test.csv
內容:
datetime,index
1999-10-10 10:10:10,0
1999-10-10 10:10:10,1
1999-10-10 10:10:10,2
1999-10-10 10:10:10,3
...
讀取這個csv檔案:
df = pd.read_csv('/tmp/test.csv') print(df.dtypes)
輸出:
datetime object
index int64
dtype: object
預設pandas並不會自動做日期型別資料的識別,datatime被識別成字串, 使用pandas自帶的推斷日期方法進行推斷:
df = pd.read_csv('/tmp/test.csv', infer_datetime_format=True, parse_dates=['datetime'])
print(df.dtypes)
輸出:
datetime datetime64[ns]
index int64
dtype: object
這種方法的問題在於需要事先知道列名,指定從哪些列裡面推斷這些列是不是日期型別,而期望pandas自動識別哪些是日期列就像識別哪些是float列一樣。
檢視一下pandas的推斷方法:
infer_datetime_format: bool, default False
If True andparse_dates
is True for a column, try to infer the
datetime format based on the first datetime string. If the format
can be inferred, there often will be a large parsing speed-up.
它的推斷方式使用第一個不為空的值嘗試轉換為日期列,如果能成功把此列當成日期列處理,否則不是。
仿照這個思路,可以來實現自動識別哪些是日期列:
- 正常讀取pd.read_csv()
- 讀取出來的df挑出來是object型別的列
- 對object型別的列取前100行非空的行,嘗試轉換成日期,如果全部成功則認為該列是日期型別
這個方法的優勢:
- 不需要事先知道csv資料中的列
- 使用前100行資料比前1行資料更靠譜,而且效能損失不大
實現參考:
df = pd.read_csv('/tmp/test.csv')
def get_categorical_cols(df: pd.DataFrame):
c_list = []
for k, v in df.dtypes.items():
if 'object' in v.name:
c_list.append(k)
return c_list
def parse_date(series: pd.Series):
format = "%Y-%m-%d %H:%M:%S" # Now only support one format
# 1. take top 100 non-empty values
INFER_TOP_N = 100
series_non_empty = series.dropna()[: INFER_TOP_N]
# 2. if these value all datetime value infer it as datetime nor object
for item in series_non_empty:
try:
if isinstance(item, str):
pd.datetime.strptime(item, format)
else:
return series
except Exception as e:
return series
# 3. infer as datetime
return pd.to_datetime(series, format=format)
categorical_cols = get_categorical_cols(df)
for c in categorical_cols:
df[c] = parse_date(df[c])
print(df.dtypes)
輸出:
datetime datetime64[ns]
index int64
dtype: object
參考: