The error signals you called to_pydatetime() on plain int64 epoch values; convert them to pandas datetimes first with pd.to_datetime(..., unit=...).
Why this matters: to_pydatetime() belongs to pandas date-time objects (like Timestamp, DatetimeIndex, or a Series’ .dt accessor). A raw numpy.int64 has no such method. When integers represent epoch time, you must convert them into real datetimes before handing them to anything that expects Python datetime objects.
What The Error Really Means
This crash happens when code tries to call .to_pydatetime() on values that are not pandas date-time objects. The method exists on pandas.Timestamp and on a datetime-typed Series via .dt.to_pydatetime(), where it returns native Python datetime objects. On a plain numpy.int64—even if the integer encodes a timestamp—there’s no such attribute, so Python raises the AttributeError.
- Know the owners:
Timestamp.to_pydatetime()converts a single pandas timestamp to a Pythondatetime. - Use the accessor:
Series.dt.to_pydatetime()turns a datetime Series into Pythondatetimeobjects. - Avoid guessing: If your column is plain
int64, convert withpd.to_datetimefirst, then call.dt.to_pydatetime()if you actually need Python objects.
Quick Checks To Confirm The Root Cause
Quick check: Print dtypes and the first values before calling any conversion. It takes seconds and prevents blind fixes.
# Inspect dtypes
print(df.dtypes)
# Spot the offender
print(type(df["ts"].iloc[0])) # numpy.int64? Timestamp? numpy.datetime64?
# Check if you accidentally grabbed a NumPy array (drops pandas dtype info)
print(type(df["ts"].values)) # numpy.ndarray means you lost the pandas dtype
- If you see
int64: Your “timestamps” are raw integers (seconds/ms/ns from epoch). Convert withpd.to_datetimeusing the rightunit. - If you see
numpy.datetime64: You already have NumPy datetimes. Either keep them, or cast to pandas datetime dtype and proceed. - If you see
Timestamp: You can safely call.dt.to_pydatetime()(Series) or.to_pydatetime()(singleTimestamp).
Correct Conversions For Common Cases
Use the right unit and keep the path short. This table gives the exact call for each source format.
| Source Values | Symptom | Safe Conversion |
|---|---|---|
| Seconds since epoch (e.g., 1697040000) | int64; AttributeError on to_pydatetime |
df["ts"] = pd.to_datetime(df["ts"], unit="s", utc=True) |
| Milliseconds since epoch | int64; wrong date if unit omitted |
df["ts"] = pd.to_datetime(df["ts"], unit="ms", utc=True) |
| Nanoseconds since epoch | int64; values look huge |
df["ts"] = pd.to_datetime(df["ts"], unit="ns", utc=True) |
numpy.datetime64 dtype |
No to_pydatetime on ints, but here you have datetimes |
df["ts"] = pd.to_datetime(df["ts"]) (already datetime-like) |
| YYYYMMDD integers (e.g., 20231011) | Parsed as plain numbers | df["date"] = pd.to_datetime(df["date"], format="%Y%m%d") |
Deeper fix: After conversion, decide if you need Python datetime objects. Many pandas and plotting APIs accept pandas datetimes directly, so calling to_pydatetime() is often unnecessary work.
Attributeerror ‘Numpy Int64’ No Attribute To_PyDateTime — Causes And Fixes
You’ll hit AttributeError: ‘NumPy Int64’ Object Has No Attribute ‘To_PyDateTime’ most often in these patterns:
- Lost the pandas dtype: Calling
df["ts"].valuesreturns a NumPy array. If the underlying dtype was plainint64, you now have raw ints. Keep the Series, or callpd.to_datetimeon it before conversion. - Wrong unit: Treating milliseconds as seconds (or nanoseconds as milliseconds) silently shifts dates. Always set
unitexplicitly. - Blind casting: Using
.astype("datetime64[ns]")on integer epoch data can fail or misinterpret values. Preferpd.to_datetime(..., unit=...), which is designed for epoch conversion. - Library expects a DatetimeIndex: Analytics/finance helpers often require an index of type
DatetimeIndex. If you pass a numeric index, internal calls toto_pydatetime()blow up.
Reliable Fix Recipes You Can Trust
Fix 1 — Convert Epoch Integers To Pandas Datetime
# seconds
df["ts"] = pd.to_datetime(df["ts"], unit="s", utc=True)
# milliseconds
df["ts"] = pd.to_datetime(df["ts"], unit="ms", utc=True)
# nanoseconds
df["ts"] = pd.to_datetime(df["ts"], unit="ns", utc=True)
- Keep UTC consistent: Set
utc=Truewhen timestamps are UTC. Localize/convert later with.dt.tz_convert("America/New_York")if needed.
Fix 2 — Build A Proper DatetimeIndex
df = df.set_index(pd.to_datetime(df["ts"], unit="s", utc=True)).sort_index()
# many libraries now accept df.index directly
- Avoid
.valueshere: Stay with the pandas index to keep datetime typing intact.
Fix 3 — From NumPy Datetime64 To Python Datetime (Only If Required)
# If you already have a pandas datetime Series:
py_datetimes = df["ts"].dt.to_pydatetime() # array of Python datetime
# Single Timestamp
py_dt = pd.Timestamp("2024-10-11 00:00:00Z").to_pydatetime()
- Prefer pandas objects: Most plotting/stats stacks consume pandas datetimes directly; skip converting to Python
datetimeunless an API demands it.
Fix 4 — YYYYMMDD Or Other Integer Date Codes
df["date"] = pd.to_datetime(df["date"], format="%Y%m%d")
- Use
formatfor non-epoch integers: This avoids expensive inference and date mistakes.
Fix 5 — When A Library Calls to_pydatetime() Internally
Some helpers expect a DatetimeIndex and will call to_pydatetime() inside their code paths. If you hand them numeric indices, they break. Set a datetime index before the call:
rets = rets.copy()
rets.index = pd.to_datetime(rets.index, unit="s", utc=True) # or matching unit
lib.create_report(rets) # stops failing on to_pydatetime()
End-To-End Example That Avoids The Trap
Scenario: You loaded trades with a ts column as epoch milliseconds and want a time-indexed DataFrame for analysis and charts—without ever touching numpy.int64.to_pydatetime.
import pandas as pd
# Raw input
df = pd.DataFrame({
"ts": [1715731200000, 1715817600000, 1715904000000], # ms
"price": [101.2, 103.0, 102.4]
})
# 1) Convert to pandas datetime (explicit unit!)
df["ts"] = pd.to_datetime(df["ts"], unit="ms", utc=True)
# 2) Set as index for downstream libraries
df = df.set_index("ts").sort_index()
# 3) Plot or pass to libraries that expect datetimes; no .to_pydatetime() needed
ax = df["price"].plot(title="Price Over Time")
Frequently Missed Details That Keep The Error Away
- Stay in pandas land: Use the Series/DataFrame directly. Pulling out
.valuestoo early throws away pandas’ datetime dtype. - Be explicit with units: Seconds vs. milliseconds vs. nanoseconds is the easiest way to get dates wildly off. Set
unitevery time you convert epoch numbers. - Convert once: Don’t bounce between pandas, NumPy, and Python
datetimewithout a reason. Each hop can drop timezone/nanoseconds. - Only call
to_pydatetime()when required: Many APIs are faster with pandas datetimes. Converting to Python objects adds overhead.
Why This Fix Matches The Libraries’ Expectations
Most time-series tools assume either a DatetimeIndex or a datetime-typed column. Passing a numeric index leaves them guessing, so they probe for conversion helpers like to_pydatetime(). If those helpers land on int64 data, your code raises AttributeError: ‘NumPy Int64’ Object Has No Attribute ‘To_PyDateTime’. Converting early with pd.to_datetime, then indexing on the result, aligns the data shape with what those tools want and removes the crash.
Copy-Paste Fix Checklist
- Inspect dtypes —
print(df.dtypes). Is the “time” columnint64? - Convert with the right unit —
pd.to_datetime(df["ts"], unit="s"|"ms"|"ns", utc=True). - Make it the index —
df = df.set_index("ts").sort_index()if the next function expects an index. - Only if needed —
df.index.to_pydatetime()ordf["ts"].dt.to_pydatetime()for APIs that demand Python objects. - Never call on ints — Don’t call
to_pydatetime()onnumpy.int64values.
Where To Go From Here
Quick pointer: Keep a tiny helper that enforces the conversion rule in one place:
def ensure_datetime(series, unit=None, tz="UTC"):
if series.dtype.kind in {"i", "u"} and unit:
out = pd.to_datetime(series, unit=unit, utc=True)
else:
out = pd.to_datetime(series, utc=True)
return out.dt.tz_convert(tz) if tz else out
# Usage
df["ts"] = ensure_datetime(df["ts"], unit="ms")
This keeps your pipelines neat, your types predictable, and avoids calling to_pydatetime() on anything that isn’t a pandas datetime.
When you see AttributeError: ‘NumPy Int64’ Object Has No Attribute ‘To_PyDateTime’ inside a plotting or backtest report, fix the dtype at the boundary and re-run. If an external tool still throws the same message, set a proper DatetimeIndex before passing the data; that’s the contract those tools expect.
