Folioevanzhou.org
← 返回 Tessera
加工1,000 行 × 15 列90 KB无缺失数据 2026-04-19

nyc_taxi_record

A cleaned random sample of 1,000 New York yellow taxi trips from October 2024, covering fare, distance, duration and payment.

One row represents one trip.

NYC TLC · 收录于 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_idIdentifier assigned by Tessera, not by TLC.字符型—不同值 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_hourHour of pickup in local time.整数—min 0q1 —中位 16.0均值 14.8q3 —max 23.0
3pickup_weekdayWeekday of pickup.字符型—不同值 7Thursday · Wednesday · Tuesday · Friday · Saturday · Sunday · Monday
4passenger_countPassenger count entered by the driver.整数—min 1q1 —中位 1均值 1.31q3 —max 6
5trip_distance_milesMetered distance in miles.双精度—min 0.14q1 —中位 1.73均值 3.22q3 —max 26.9
6trip_duration_min= (dropoff − pickup) seconds / 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_usdkeyMetered fare in USD, before tips and tolls.双精度—min 3.7q1 —中位 14.2均值 19.2q3 —max 127.6
9tip_amount_usdTip in USD, credit card tips only.双精度—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_usdTolls in USD.双精度—min 0q1 —中位 0均值 0.477q3 —max 20.3
12total_amount_usdTotal charged to the passenger.双精度—min 5.9q1 —中位 21.8均值 28.4q3 —max 148.9
13payment_typeMapped from the TLC payment_type code via PAYMENT_TYPES.字符型—不同值 4credit_card · cash · dispute · no_charge
14rate_codeMapped from the TLC RatecodeID via RATE_CODES.字符型—不同值 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

Source

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

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

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

Use cases

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

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

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

生成脚本Python · 172 行
"""
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

# 产物写到 ../csv/nyc_taxi_record.csv —— 脚本和 CSV 是 content/tessera/data/ 下固定的兄弟目录,
# 所以按脚本自身定位,不依赖你在哪个目录敲这条命令。csv/ 不进仓库(见 .gitignore)。
OUT = Path(__file__).resolve().parent.parent / "csv" / "nyc_taxi_record.csv"
OUT.parent.mkdir(parents=True, exist_ok=True)


SOURCE_URL = (
    "https://d37ci6vzurychx.cloudfront.net/trip-data/"
    "yellow_tripdata_2024-10.parquet"
)
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 数出。