|
|
FishC 发表于 2026-2-23 23:57
@FishC 那pandas是如何预处理日期列呢??假设A列是日期字符串,格式为“YYYY-MM”,拆分为年列和 ...
Data-Forge 没有直接在解析函数中设置 `errors='coerce'` 的参数,但可以通过组合其他方法实现类似效果。主要思路是先尝试解析,将解析失败的值替换为 null(DataFrame 中的 `null` 或 `undefined`)。
具体步骤如下:
1. 使用 .parseDates() 或 .parseFloats() 等函数尝试转换列。对于自定义格式或更复杂的场景,通常先用 .map() 或 .select() 进行预处理。
2. 在映射函数中,用 try-catch 或条件判断来处理不规范的日期字符串,将解析失败的值返回为 `null`。
3. 解析后,列中的 `null` 值就相当于 pandas 的 `NaT`。
**示例:假设你的日期字符串列为“YYYY-MM”,但混入了无效数据**
- const DataForge = require('data-forge');
- // 假设原始 DataFrame 有一个 'date_str' 列,包含不规范数据
- let df = new DataForge.DataFrame({
- columnNames: ['date_str'],
- rows: [
- ['2023-01'],
- ['2023-13'], // 无效月份
- ['2023-02'],
- ['not-a-date'], // 无效字符串
- ['2024-05']
- ]
- });
- // 使用 .select() 创建新列,尝试解析日期
- df = df.select(row => {
- // 复制原有行数据
- const newRow = Object.assign({}, row);
-
- // 尝试解析日期字符串
- let parsedDate = null;
- const dateStr = row.date_str;
- // 简单的正则匹配 YYYY-MM 格式
- const match = dateStr.match(/^(\d{4})-(\d{2})$/);
- if (match) {
- const year = parseInt(match[1], 10);
- const month = parseInt(match[2], 10);
- // 检查月份是否有效
- if (month >= 1 && month <= 12) {
- // 创建一个日期对象(这里设置为该月的第一天)
- parsedDate = new Date(year, month - 1, 1);
- // 验证 Date 对象是否有效(比如年份超出范围)
- if (isNaN(parsedDate.getTime())) {
- parsedDate = null;
- }
- }
- }
- // 如果解析成功,parsedDate 是一个 Date 对象;否则为 null
- newRow.parsed_date = parsedDate;
-
- return newRow;
- });
- console.log(df.toString());
复制代码
**输出结果:**
- date_str parsed_date
- 2023-01 Thu Dec 01 2022 ... (Date 对象)
- 2023-13 null
- 2023-02 Wed Feb 01 2023 ...
- not-a-date null
- 2024-05 Wed May 01 2024 ...
复制代码
**进一步拆分年、月列:**
- // 接着上面的 df,我们可以从 parsed_date 列提取年、月
- df = df.select(row => {
- const newRow = Object.assign({}, row);
- if (row.parsed_date instanceof Date && !isNaN(row.parsed_date.getTime())) {
- newRow.year = row.parsed_date.getFullYear();
- newRow.month = row.parsed_date.getMonth() + 1; // 月份从0开始
- } else {
- newRow.year = null;
- newRow.month = null;
- }
- return newRow;
- });
- // 选择需要的列
- df = df.select(['date_str', 'year', 'month']);
- console.log(df.toString());
复制代码
**更简洁的方法(使用 Series.map):**
你也可以先提取列为 Series,进行转换,再放回 DataFrame。
- let dateSeries = df.getSeries('date_str');
- // 定义一个解析函数
- function parseYearMonth(value) {
- const match = value.match(/^(\d{4})-(\d{2})$/);
- if (match) {
- const year = parseInt(match[1], 10);
- const month = parseInt(match[2], 10);
- if (month >= 1 && month <= 12) {
- const date = new Date(year, month - 1, 1);
- if (!isNaN(date.getTime())) {
- return date;
- }
- }
- }
- return null; // 解析失败返回 null
- }
- const parsedSeries = dateSeries.map(parseYearMonth);
- // 将解析后的 Series 添加为新列
- df = df.withSeries('parsed_date', parsedSeries);
- console.log(df.toString());
复制代码
**总结对比:**
- pandas: pd.to_datetime(df['A'], format='%Y-%m', errors='coerce')
- Data-Forge: 需要编写一个自定义的解析函数,在 .map() 或 .select() 中调用,将无效输入返回 null。
所以,Data-Forge 没有内置的一次性参数,但通过函数式编程的方式可以轻松实现相同的“强制转换并置为 null”的效果。解析后,你就可以放心地提取年、月等信息了。
以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。 |
|