← 返回 Tessera
交通1,000 行 × 1590 KB无缺失数据 2026-04-19

nyc_taxi_record

一千条清洗过的出租车行程,钱、距离、时长、时段、支付方式俱全——练相关、散点、分时段汇总和"钱对钱"那类图的现成样本。

NYC TLC Yellow Taxi Trip Records(2024-10) · 收录于 2026-04-19

下载 CSV · 90 KB
数据预览6
trip_idpickup_hourpickup_weekdaypassenger_counttrip_distance_milestrip_duration_minavg_speed_mphfare_amount_usdtip_amount_usdtip_pcttolls_amount_usdtotal_amount_usdpayment_typerate_codeis_airport_rate
yt_202410_000121Wednesday28.9928.718.841.59.30.2055.8credit_cardstandardFalse
yt_202410_000222Friday22.7726.26.322.65.520.2033.1credit_cardstandardFalse
yt_202410_000320Friday10.7759.26.52.30.2013.8credit_cardstandardFalse
yt_202410_000413Tuesday111.540.717.050.600061.4cashstandardFalse
yt_202410_000513Monday11.6123.14.219.85.950.25029.8credit_cardstandardFalse
yt_202410_000620Friday51.659.610.310.700015.7cashstandardFalse
变量15
字符型4整数2双精度8逻辑型1
类型
#变量类型缺失统计
1trip_idkey字符型不同值 1000yt_202410_0001 · yt_202410_0002 · yt_202410_0003 · yt_202410_0004 · yt_202410_0005 · yt_202410_0006 · yt_202410_0007 · yt_202410_0008
2pickup_hour整数min 0q1 中位 16.0均值 14.8q3 max 23.0
3pickup_weekday字符型不同值 7Thursday · Wednesday · Tuesday · Friday · Saturday · Sunday · Monday
4passenger_count整数min 1q1 中位 1均值 1.31q3 max 6
5trip_distance_miles双精度min 0.14q1 中位 1.73均值 3.22q3 max 26.9
6trip_duration_min= (dropoff − pickup) 秒 / 60双精度min 1q1 中位 13.4均值 17.0q3 max 92.8
7avg_speed_mph= trip_distance_miles / (trip_duration_min / 60)双精度min 1q1 中位 8.6均值 10.3q3 max 46.3
8fare_amount_usd双精度min 3.7q1 中位 14.2均值 19.2q3 max 127.6
9tip_amount_usd双精度min 0q1 中位 3均值 3.73q3 max 75.0
10tip_pct= tip_amount_usd / (total_amount_usd − tip_amount_usd)双精度min 0q1 中位 0.2均值 0.154q3 max 1.32
11tolls_amount_usd双精度min 0q1 中位 0均值 0.477q3 max 20.3
12total_amount_usd双精度min 5.9q1 中位 21.8均值 28.4q3 max 148.9
13payment_typePAYMENT_TYPES 映射自 TLC 的 payment_type 编码字符型不同值 4credit_card · cash · dispute · no_charge
14rate_codeRATE_CODES 映射自 TLC 的 RatecodeID字符型不同值 6standard · jfk · unknown · nassau_westchester · negotiated · newark
15is_airport_rate= rate_code in ("jfk", "newark")逻辑型 32 968
载入已写好列类型
library(readr)

nyc_taxi_record <- read_csv(
  "https://assets.evanzhou.org/tessera/csv/nyc_taxi_record.csv",
  col_types = cols(
    trip_id             = col_character(),
    pickup_hour         = col_integer(),
    pickup_weekday      = col_character(),
    passenger_count     = col_integer(),
    trip_distance_miles = col_double(),
    trip_duration_min   = col_double(),
    avg_speed_mph       = col_double(),
    fare_amount_usd     = col_double(),
    tip_amount_usd      = col_double(),
    tip_pct             = col_double(),
    tolls_amount_usd    = col_double(),
    total_amount_usd    = col_double(),
    payment_type        = col_character(),
    rate_code           = col_character(),
    is_airport_rate     = col_logical()
  )
)
URLhttps://assets.evanzhou.org/tessera/csv/nyc_taxi_record.csv

来源

纽约市出租车与豪华轿车委员会(TLC)公开的黄色出租车行程记录,取 2024 年 10 月那一份 parquet,清洗后随机抽 1000 条(random_state=42,所以可复现)。一行是一次行程。

它不是原始数据,是清洗后的样本。 脚本按一串区间做了过滤:时长 1–120 分钟、距离 0.1–50 英里、均速 1–70 英里/时、票价和总额为正、乘客 1–6 人、小费比例 0–150%。极端值、零距离行程、退单记录在这一步就被剔掉了。

所以这份数据没有缺失、也几乎没有离群点——这既是它好上手的原因,也是它的局限:拿它练异常值检测是没有靶子的。

适用图形

十一个数值列彼此相关,是这批数据里最适合做相关性分析的一份。

图形结构 用途
相关性热图 距离、时长、均速、票价、小费之间的相关结构
散点图 + 拟合 票价对距离——这条关系接近线性,是讲回归的好例子
分时段箱线图 pickup_hour 看均速的昼夜差
分组小提琴 payment_type 比小费比例
堆叠条形图 星期 × 支付方式的构成

payment_typerate_code 都是少数几档的分类变量,正好试 5 色以内的定性配色。is_airport_rate 只有 32 条为真——按它分组时记得这是个很不平衡的划分。

生成脚本Python · 168
"""
nyc_taxi_record.py

Build a compact NYC Yellow Taxi toy dataset.

Source:
- NYC Taxi and Limousine Commission Yellow Taxi Trip Records.

Output:
- assets/toy/transport/nyc_taxi_record.csv
"""

from pathlib import Path

import numpy as np
import pandas as pd


SOURCE_URL = (
    "https://d37ci6vzurychx.cloudfront.net/trip-data/"
    "yellow_tripdata_2024-10.parquet"
)
OUT = Path(__file__).with_name("nyc_taxi_record.csv")
SAMPLE_ROWS = 1000
RANDOM_STATE = 42

RAW_COLUMNS = [
    "tpep_pickup_datetime",
    "tpep_dropoff_datetime",
    "passenger_count",
    "trip_distance",
    "RatecodeID",
    "payment_type",
    "fare_amount",
    "tip_amount",
    "tolls_amount",
    "total_amount",
]

PAYMENT_TYPES = {
    1: "credit_card",
    2: "cash",
    3: "no_charge",
    4: "dispute",
    5: "unknown",
    6: "voided_trip",
}

RATE_CODES = {
    1: "standard",
    2: "jfk",
    3: "newark",
    4: "nassau_westchester",
    5: "negotiated",
    6: "group_ride",
    99: "unknown",
}


def read_source() -> pd.DataFrame:
    print(f"Reading {SOURCE_URL}")
    return pd.read_parquet(SOURCE_URL, columns=RAW_COLUMNS)


def clean_trips(raw: pd.DataFrame) -> pd.DataFrame:
    data = raw.copy()
    data["pickup_datetime"] = pd.to_datetime(data["tpep_pickup_datetime"])
    data["dropoff_datetime"] = pd.to_datetime(data["tpep_dropoff_datetime"])

    data["trip_duration_min"] = (
        data["dropoff_datetime"] - data["pickup_datetime"]
    ).dt.total_seconds() / 60

    data.rename(
        columns={
            "passenger_count": "passenger_count",
            "trip_distance": "trip_distance_miles",
            "RatecodeID": "rate_code_id",
            "fare_amount": "fare_amount_usd",
            "tip_amount": "tip_amount_usd",
            "tolls_amount": "tolls_amount_usd",
            "total_amount": "total_amount_usd",
        },
        inplace=True,
    )

    data = data.loc[
        (data["pickup_datetime"] >= "2024-10-01")
        & (data["pickup_datetime"] < "2024-11-01")
        & (data["trip_duration_min"].between(1, 120))
        & (data["trip_distance_miles"].between(0.1, 50))
        & (data["fare_amount_usd"] > 0)
        & (data["total_amount_usd"] > 0)
        & (data["passenger_count"].between(1, 6))
    ].copy()

    data["avg_speed_mph"] = (
        data["trip_distance_miles"] / (data["trip_duration_min"] / 60)
    )
    data = data.loc[data["avg_speed_mph"].between(1, 70)].copy()

    pretax_tip_base = data["total_amount_usd"] - data["tip_amount_usd"]
    data["tip_pct"] = np.where(
        pretax_tip_base > 0,
        data["tip_amount_usd"] / pretax_tip_base,
        np.nan,
    )
    data = data.loc[data["tip_pct"].between(0, 1.5) | data["tip_pct"].isna()].copy()

    data["pickup_hour"] = data["pickup_datetime"].dt.hour
    data["pickup_weekday"] = data["pickup_datetime"].dt.day_name()
    data["payment_type"] = data["payment_type"].map(PAYMENT_TYPES).fillna("unknown")
    data["rate_code"] = data["rate_code_id"].map(RATE_CODES).fillna("unknown")
    data["is_airport_rate"] = data["rate_code"].isin(["jfk", "newark"])
    data["passenger_count"] = data["passenger_count"].astype(int)

    money_columns = [
        "fare_amount_usd",
        "tip_amount_usd",
        "tolls_amount_usd",
        "total_amount_usd",
    ]
    data[money_columns] = data[money_columns].round(2)
    data["trip_distance_miles"] = data["trip_distance_miles"].round(2)
    data["trip_duration_min"] = data["trip_duration_min"].round(1)
    data["avg_speed_mph"] = data["avg_speed_mph"].round(1)
    data["tip_pct"] = data["tip_pct"].round(3)

    columns = [
        "pickup_hour",
        "pickup_weekday",
        "passenger_count",
        "trip_distance_miles",
        "trip_duration_min",
        "avg_speed_mph",
        "fare_amount_usd",
        "tip_amount_usd",
        "tip_pct",
        "tolls_amount_usd",
        "total_amount_usd",
        "payment_type",
        "rate_code",
        "is_airport_rate",
    ]
    return data[columns].reset_index(drop=True)


def main() -> None:
    raw = read_source()
    cleaned = clean_trips(raw)

    if len(cleaned) < SAMPLE_ROWS:
        raise RuntimeError(
            f"Only {len(cleaned)} rows remain after cleaning; "
            f"need at least {SAMPLE_ROWS}."
        )

    sample = cleaned.sample(n=SAMPLE_ROWS, random_state=RANDOM_STATE).reset_index(
        drop=True
    )
    sample.insert(0, "trip_id", [f"yt_202410_{i:04d}" for i in range(1, len(sample) + 1)])

    sample.to_csv(OUT, index=False)
    print(f"Done: {len(sample)} rows saved to {OUT}")


if __name__ == "__main__":
    main()

表中统计由 scripts/profile_dataset.py 于 2026-08-03 数出。