test_datetimes.py 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606
  1. import datetime as dt
  2. from datetime import datetime
  3. import dateutil
  4. import numpy as np
  5. import pytest
  6. import pandas as pd
  7. from pandas import (
  8. DataFrame,
  9. DatetimeIndex,
  10. Index,
  11. MultiIndex,
  12. Series,
  13. Timestamp,
  14. concat,
  15. date_range,
  16. to_timedelta,
  17. )
  18. import pandas._testing as tm
  19. class TestDatetimeConcat:
  20. def test_concat_datetime64_block(self):
  21. rng = date_range("1/1/2000", periods=10)
  22. df = DataFrame({"time": rng})
  23. result = concat([df, df])
  24. assert (result.iloc[:10]["time"] == rng).all()
  25. assert (result.iloc[10:]["time"] == rng).all()
  26. def test_concat_datetime_datetime64_frame(self):
  27. # GH#2624
  28. rows = []
  29. rows.append([datetime(2010, 1, 1), 1])
  30. rows.append([datetime(2010, 1, 2), "hi"])
  31. df2_obj = DataFrame.from_records(rows, columns=["date", "test"])
  32. ind = date_range(start="2000/1/1", freq="D", periods=10)
  33. df1 = DataFrame({"date": ind, "test": range(10)})
  34. # it works!
  35. concat([df1, df2_obj])
  36. def test_concat_datetime_timezone(self):
  37. # GH 18523
  38. idx1 = date_range("2011-01-01", periods=3, freq="h", tz="Europe/Paris")
  39. idx2 = date_range(start=idx1[0], end=idx1[-1], freq="h")
  40. df1 = DataFrame({"a": [1, 2, 3]}, index=idx1)
  41. df2 = DataFrame({"b": [1, 2, 3]}, index=idx2)
  42. result = concat([df1, df2], axis=1)
  43. exp_idx = DatetimeIndex(
  44. [
  45. "2011-01-01 00:00:00+01:00",
  46. "2011-01-01 01:00:00+01:00",
  47. "2011-01-01 02:00:00+01:00",
  48. ],
  49. dtype="M8[ns, Europe/Paris]",
  50. freq="h",
  51. )
  52. expected = DataFrame(
  53. [[1, 1], [2, 2], [3, 3]], index=exp_idx, columns=["a", "b"]
  54. )
  55. tm.assert_frame_equal(result, expected)
  56. idx3 = date_range("2011-01-01", periods=3, freq="h", tz="Asia/Tokyo")
  57. df3 = DataFrame({"b": [1, 2, 3]}, index=idx3)
  58. result = concat([df1, df3], axis=1)
  59. exp_idx = DatetimeIndex(
  60. [
  61. "2010-12-31 15:00:00+00:00",
  62. "2010-12-31 16:00:00+00:00",
  63. "2010-12-31 17:00:00+00:00",
  64. "2010-12-31 23:00:00+00:00",
  65. "2011-01-01 00:00:00+00:00",
  66. "2011-01-01 01:00:00+00:00",
  67. ]
  68. ).as_unit("ns")
  69. expected = DataFrame(
  70. [
  71. [np.nan, 1],
  72. [np.nan, 2],
  73. [np.nan, 3],
  74. [1, np.nan],
  75. [2, np.nan],
  76. [3, np.nan],
  77. ],
  78. index=exp_idx,
  79. columns=["a", "b"],
  80. )
  81. tm.assert_frame_equal(result, expected)
  82. # GH 13783: Concat after resample
  83. result = concat([df1.resample("h").mean(), df2.resample("h").mean()], sort=True)
  84. expected = DataFrame(
  85. {"a": [1, 2, 3] + [np.nan] * 3, "b": [np.nan] * 3 + [1, 2, 3]},
  86. index=idx1.append(idx1),
  87. )
  88. tm.assert_frame_equal(result, expected)
  89. def test_concat_datetimeindex_freq(self):
  90. # GH 3232
  91. # Monotonic index result
  92. dr = date_range("01-Jan-2013", periods=100, freq="50ms", tz="UTC")
  93. data = list(range(100))
  94. expected = DataFrame(data, index=dr)
  95. result = concat([expected[:50], expected[50:]])
  96. tm.assert_frame_equal(result, expected)
  97. # Non-monotonic index result
  98. result = concat([expected[50:], expected[:50]])
  99. expected = DataFrame(data[50:] + data[:50], index=dr[50:].append(dr[:50]))
  100. expected.index._data.freq = None
  101. tm.assert_frame_equal(result, expected)
  102. def test_concat_multiindex_datetime_object_index(self):
  103. # https://github.com/pandas-dev/pandas/issues/11058
  104. idx = Index(
  105. [dt.date(2013, 1, 1), dt.date(2014, 1, 1), dt.date(2015, 1, 1)],
  106. dtype="object",
  107. )
  108. s = Series(
  109. ["a", "b"],
  110. index=MultiIndex.from_arrays(
  111. [
  112. [1, 2],
  113. idx[:-1],
  114. ],
  115. names=["first", "second"],
  116. ),
  117. )
  118. s2 = Series(
  119. ["a", "b"],
  120. index=MultiIndex.from_arrays(
  121. [[1, 2], idx[::2]],
  122. names=["first", "second"],
  123. ),
  124. )
  125. mi = MultiIndex.from_arrays(
  126. [[1, 2, 2], idx],
  127. names=["first", "second"],
  128. )
  129. assert mi.levels[1].dtype == object
  130. expected = DataFrame(
  131. [["a", "a"], ["b", np.nan], [np.nan, "b"]],
  132. index=mi,
  133. )
  134. result = concat([s, s2], axis=1)
  135. tm.assert_frame_equal(result, expected)
  136. def test_concat_NaT_series(self):
  137. # GH 11693
  138. # test for merging NaT series with datetime series.
  139. x = Series(
  140. date_range("20151124 08:00", "20151124 09:00", freq="1h", tz="US/Eastern")
  141. )
  142. y = Series(pd.NaT, index=[0, 1], dtype="datetime64[ns, US/Eastern]")
  143. expected = Series([x[0], x[1], pd.NaT, pd.NaT])
  144. result = concat([x, y], ignore_index=True)
  145. tm.assert_series_equal(result, expected)
  146. # all NaT with tz
  147. expected = Series(pd.NaT, index=range(4), dtype="datetime64[ns, US/Eastern]")
  148. result = concat([y, y], ignore_index=True)
  149. tm.assert_series_equal(result, expected)
  150. def test_concat_NaT_series2(self):
  151. # without tz
  152. x = Series(date_range("20151124 08:00", "20151124 09:00", freq="1h"))
  153. y = Series(date_range("20151124 10:00", "20151124 11:00", freq="1h"))
  154. y[:] = pd.NaT
  155. expected = Series([x[0], x[1], pd.NaT, pd.NaT])
  156. result = concat([x, y], ignore_index=True)
  157. tm.assert_series_equal(result, expected)
  158. # all NaT without tz
  159. x[:] = pd.NaT
  160. expected = Series(pd.NaT, index=range(4), dtype="datetime64[ns]")
  161. result = concat([x, y], ignore_index=True)
  162. tm.assert_series_equal(result, expected)
  163. @pytest.mark.parametrize("tz", [None, "UTC"])
  164. def test_concat_NaT_dataframes(self, tz):
  165. # GH 12396
  166. dti = DatetimeIndex([pd.NaT, pd.NaT], tz=tz)
  167. first = DataFrame({0: dti})
  168. second = DataFrame(
  169. [[Timestamp("2015/01/01", tz=tz)], [Timestamp("2016/01/01", tz=tz)]],
  170. index=[2, 3],
  171. )
  172. expected = DataFrame(
  173. [
  174. pd.NaT,
  175. pd.NaT,
  176. Timestamp("2015/01/01", tz=tz),
  177. Timestamp("2016/01/01", tz=tz),
  178. ]
  179. )
  180. result = concat([first, second], axis=0)
  181. tm.assert_frame_equal(result, expected)
  182. @pytest.mark.parametrize("tz1", [None, "UTC"])
  183. @pytest.mark.parametrize("tz2", [None, "UTC"])
  184. @pytest.mark.parametrize("item", [pd.NaT, Timestamp("20150101")])
  185. def test_concat_NaT_dataframes_all_NaT_axis_0(
  186. self, tz1, tz2, item, using_array_manager
  187. ):
  188. # GH 12396
  189. # tz-naive
  190. first = DataFrame([[pd.NaT], [pd.NaT]]).apply(lambda x: x.dt.tz_localize(tz1))
  191. second = DataFrame([item]).apply(lambda x: x.dt.tz_localize(tz2))
  192. result = concat([first, second], axis=0)
  193. expected = DataFrame(Series([pd.NaT, pd.NaT, item], index=[0, 1, 0]))
  194. expected = expected.apply(lambda x: x.dt.tz_localize(tz2))
  195. if tz1 != tz2:
  196. expected = expected.astype(object)
  197. if item is pd.NaT and not using_array_manager:
  198. # GH#18463
  199. # TODO: setting nan here is to keep the test passing as we
  200. # make assert_frame_equal stricter, but is nan really the
  201. # ideal behavior here?
  202. if tz1 is not None:
  203. expected.iloc[-1, 0] = np.nan
  204. else:
  205. expected.iloc[:-1, 0] = np.nan
  206. tm.assert_frame_equal(result, expected)
  207. @pytest.mark.parametrize("tz1", [None, "UTC"])
  208. @pytest.mark.parametrize("tz2", [None, "UTC"])
  209. def test_concat_NaT_dataframes_all_NaT_axis_1(self, tz1, tz2):
  210. # GH 12396
  211. first = DataFrame(Series([pd.NaT, pd.NaT]).dt.tz_localize(tz1))
  212. second = DataFrame(Series([pd.NaT]).dt.tz_localize(tz2), columns=[1])
  213. expected = DataFrame(
  214. {
  215. 0: Series([pd.NaT, pd.NaT]).dt.tz_localize(tz1),
  216. 1: Series([pd.NaT, pd.NaT]).dt.tz_localize(tz2),
  217. }
  218. )
  219. result = concat([first, second], axis=1)
  220. tm.assert_frame_equal(result, expected)
  221. @pytest.mark.parametrize("tz1", [None, "UTC"])
  222. @pytest.mark.parametrize("tz2", [None, "UTC"])
  223. def test_concat_NaT_series_dataframe_all_NaT(self, tz1, tz2):
  224. # GH 12396
  225. # tz-naive
  226. first = Series([pd.NaT, pd.NaT]).dt.tz_localize(tz1)
  227. second = DataFrame(
  228. [
  229. [Timestamp("2015/01/01", tz=tz2)],
  230. [Timestamp("2016/01/01", tz=tz2)],
  231. ],
  232. index=[2, 3],
  233. )
  234. expected = DataFrame(
  235. [
  236. pd.NaT,
  237. pd.NaT,
  238. Timestamp("2015/01/01", tz=tz2),
  239. Timestamp("2016/01/01", tz=tz2),
  240. ]
  241. )
  242. if tz1 != tz2:
  243. expected = expected.astype(object)
  244. result = concat([first, second])
  245. tm.assert_frame_equal(result, expected)
  246. class TestTimezoneConcat:
  247. def test_concat_tz_series(self):
  248. # gh-11755: tz and no tz
  249. x = Series(date_range("20151124 08:00", "20151124 09:00", freq="1h", tz="UTC"))
  250. y = Series(date_range("2012-01-01", "2012-01-02"))
  251. expected = Series([x[0], x[1], y[0], y[1]], dtype="object")
  252. result = concat([x, y], ignore_index=True)
  253. tm.assert_series_equal(result, expected)
  254. def test_concat_tz_series2(self):
  255. # gh-11887: concat tz and object
  256. x = Series(date_range("20151124 08:00", "20151124 09:00", freq="1h", tz="UTC"))
  257. y = Series(["a", "b"])
  258. expected = Series([x[0], x[1], y[0], y[1]], dtype="object")
  259. result = concat([x, y], ignore_index=True)
  260. tm.assert_series_equal(result, expected)
  261. def test_concat_tz_series3(self, unit, unit2):
  262. # see gh-12217 and gh-12306
  263. # Concatenating two UTC times
  264. first = DataFrame([[datetime(2016, 1, 1)]], dtype=f"M8[{unit}]")
  265. first[0] = first[0].dt.tz_localize("UTC")
  266. second = DataFrame([[datetime(2016, 1, 2)]], dtype=f"M8[{unit2}]")
  267. second[0] = second[0].dt.tz_localize("UTC")
  268. result = concat([first, second])
  269. exp_unit = tm.get_finest_unit(unit, unit2)
  270. assert result[0].dtype == f"datetime64[{exp_unit}, UTC]"
  271. def test_concat_tz_series4(self, unit, unit2):
  272. # Concatenating two London times
  273. first = DataFrame([[datetime(2016, 1, 1)]], dtype=f"M8[{unit}]")
  274. first[0] = first[0].dt.tz_localize("Europe/London")
  275. second = DataFrame([[datetime(2016, 1, 2)]], dtype=f"M8[{unit2}]")
  276. second[0] = second[0].dt.tz_localize("Europe/London")
  277. result = concat([first, second])
  278. exp_unit = tm.get_finest_unit(unit, unit2)
  279. assert result[0].dtype == f"datetime64[{exp_unit}, Europe/London]"
  280. def test_concat_tz_series5(self, unit, unit2):
  281. # Concatenating 2+1 London times
  282. first = DataFrame(
  283. [[datetime(2016, 1, 1)], [datetime(2016, 1, 2)]], dtype=f"M8[{unit}]"
  284. )
  285. first[0] = first[0].dt.tz_localize("Europe/London")
  286. second = DataFrame([[datetime(2016, 1, 3)]], dtype=f"M8[{unit2}]")
  287. second[0] = second[0].dt.tz_localize("Europe/London")
  288. result = concat([first, second])
  289. exp_unit = tm.get_finest_unit(unit, unit2)
  290. assert result[0].dtype == f"datetime64[{exp_unit}, Europe/London]"
  291. def test_concat_tz_series6(self, unit, unit2):
  292. # Concatenating 1+2 London times
  293. first = DataFrame([[datetime(2016, 1, 1)]], dtype=f"M8[{unit}]")
  294. first[0] = first[0].dt.tz_localize("Europe/London")
  295. second = DataFrame(
  296. [[datetime(2016, 1, 2)], [datetime(2016, 1, 3)]], dtype=f"M8[{unit2}]"
  297. )
  298. second[0] = second[0].dt.tz_localize("Europe/London")
  299. result = concat([first, second])
  300. exp_unit = tm.get_finest_unit(unit, unit2)
  301. assert result[0].dtype == f"datetime64[{exp_unit}, Europe/London]"
  302. def test_concat_tz_series_tzlocal(self):
  303. # see gh-13583
  304. x = [
  305. Timestamp("2011-01-01", tz=dateutil.tz.tzlocal()),
  306. Timestamp("2011-02-01", tz=dateutil.tz.tzlocal()),
  307. ]
  308. y = [
  309. Timestamp("2012-01-01", tz=dateutil.tz.tzlocal()),
  310. Timestamp("2012-02-01", tz=dateutil.tz.tzlocal()),
  311. ]
  312. result = concat([Series(x), Series(y)], ignore_index=True)
  313. tm.assert_series_equal(result, Series(x + y))
  314. assert result.dtype == "datetime64[ns, tzlocal()]"
  315. def test_concat_tz_series_with_datetimelike(self):
  316. # see gh-12620: tz and timedelta
  317. x = [
  318. Timestamp("2011-01-01", tz="US/Eastern"),
  319. Timestamp("2011-02-01", tz="US/Eastern"),
  320. ]
  321. y = [pd.Timedelta("1 day"), pd.Timedelta("2 day")]
  322. result = concat([Series(x), Series(y)], ignore_index=True)
  323. tm.assert_series_equal(result, Series(x + y, dtype="object"))
  324. # tz and period
  325. y = [pd.Period("2011-03", freq="M"), pd.Period("2011-04", freq="M")]
  326. result = concat([Series(x), Series(y)], ignore_index=True)
  327. tm.assert_series_equal(result, Series(x + y, dtype="object"))
  328. def test_concat_tz_frame(self):
  329. df2 = DataFrame(
  330. {
  331. "A": Timestamp("20130102", tz="US/Eastern"),
  332. "B": Timestamp("20130603", tz="CET"),
  333. },
  334. index=range(5),
  335. )
  336. # concat
  337. df3 = concat([df2.A.to_frame(), df2.B.to_frame()], axis=1)
  338. tm.assert_frame_equal(df2, df3)
  339. def test_concat_multiple_tzs(self):
  340. # GH#12467
  341. # combining datetime tz-aware and naive DataFrames
  342. ts1 = Timestamp("2015-01-01", tz=None)
  343. ts2 = Timestamp("2015-01-01", tz="UTC")
  344. ts3 = Timestamp("2015-01-01", tz="EST")
  345. df1 = DataFrame({"time": [ts1]})
  346. df2 = DataFrame({"time": [ts2]})
  347. df3 = DataFrame({"time": [ts3]})
  348. results = concat([df1, df2]).reset_index(drop=True)
  349. expected = DataFrame({"time": [ts1, ts2]}, dtype=object)
  350. tm.assert_frame_equal(results, expected)
  351. results = concat([df1, df3]).reset_index(drop=True)
  352. expected = DataFrame({"time": [ts1, ts3]}, dtype=object)
  353. tm.assert_frame_equal(results, expected)
  354. results = concat([df2, df3]).reset_index(drop=True)
  355. expected = DataFrame({"time": [ts2, ts3]})
  356. tm.assert_frame_equal(results, expected)
  357. def test_concat_multiindex_with_tz(self):
  358. # GH 6606
  359. df = DataFrame(
  360. {
  361. "dt": DatetimeIndex(
  362. [
  363. datetime(2014, 1, 1),
  364. datetime(2014, 1, 2),
  365. datetime(2014, 1, 3),
  366. ],
  367. dtype="M8[ns, US/Pacific]",
  368. ),
  369. "b": ["A", "B", "C"],
  370. "c": [1, 2, 3],
  371. "d": [4, 5, 6],
  372. }
  373. )
  374. df = df.set_index(["dt", "b"])
  375. exp_idx1 = DatetimeIndex(
  376. ["2014-01-01", "2014-01-02", "2014-01-03"] * 2,
  377. dtype="M8[ns, US/Pacific]",
  378. name="dt",
  379. )
  380. exp_idx2 = Index(["A", "B", "C"] * 2, name="b")
  381. exp_idx = MultiIndex.from_arrays([exp_idx1, exp_idx2])
  382. expected = DataFrame(
  383. {"c": [1, 2, 3] * 2, "d": [4, 5, 6] * 2}, index=exp_idx, columns=["c", "d"]
  384. )
  385. result = concat([df, df])
  386. tm.assert_frame_equal(result, expected)
  387. def test_concat_tz_not_aligned(self):
  388. # GH#22796
  389. ts = pd.to_datetime([1, 2]).tz_localize("UTC")
  390. a = DataFrame({"A": ts})
  391. b = DataFrame({"A": ts, "B": ts})
  392. result = concat([a, b], sort=True, ignore_index=True)
  393. expected = DataFrame(
  394. {"A": list(ts) + list(ts), "B": [pd.NaT, pd.NaT] + list(ts)}
  395. )
  396. tm.assert_frame_equal(result, expected)
  397. @pytest.mark.parametrize(
  398. "t1",
  399. [
  400. "2015-01-01",
  401. pytest.param(
  402. pd.NaT,
  403. marks=pytest.mark.xfail(
  404. reason="GH23037 incorrect dtype when concatenating"
  405. ),
  406. ),
  407. ],
  408. )
  409. def test_concat_tz_NaT(self, t1):
  410. # GH#22796
  411. # Concatenating tz-aware multicolumn DataFrames
  412. ts1 = Timestamp(t1, tz="UTC")
  413. ts2 = Timestamp("2015-01-01", tz="UTC")
  414. ts3 = Timestamp("2015-01-01", tz="UTC")
  415. df1 = DataFrame([[ts1, ts2]])
  416. df2 = DataFrame([[ts3]])
  417. result = concat([df1, df2])
  418. expected = DataFrame([[ts1, ts2], [ts3, pd.NaT]], index=[0, 0])
  419. tm.assert_frame_equal(result, expected)
  420. def test_concat_tz_with_empty(self):
  421. # GH 9188
  422. result = concat(
  423. [DataFrame(date_range("2000", periods=1, tz="UTC")), DataFrame()]
  424. )
  425. expected = DataFrame(date_range("2000", periods=1, tz="UTC"))
  426. tm.assert_frame_equal(result, expected)
  427. class TestPeriodConcat:
  428. def test_concat_period_series(self):
  429. x = Series(pd.PeriodIndex(["2015-11-01", "2015-12-01"], freq="D"))
  430. y = Series(pd.PeriodIndex(["2015-10-01", "2016-01-01"], freq="D"))
  431. expected = Series([x[0], x[1], y[0], y[1]], dtype="Period[D]")
  432. result = concat([x, y], ignore_index=True)
  433. tm.assert_series_equal(result, expected)
  434. def test_concat_period_multiple_freq_series(self):
  435. x = Series(pd.PeriodIndex(["2015-11-01", "2015-12-01"], freq="D"))
  436. y = Series(pd.PeriodIndex(["2015-10-01", "2016-01-01"], freq="M"))
  437. expected = Series([x[0], x[1], y[0], y[1]], dtype="object")
  438. result = concat([x, y], ignore_index=True)
  439. tm.assert_series_equal(result, expected)
  440. assert result.dtype == "object"
  441. def test_concat_period_other_series(self):
  442. x = Series(pd.PeriodIndex(["2015-11-01", "2015-12-01"], freq="D"))
  443. y = Series(pd.PeriodIndex(["2015-11-01", "2015-12-01"], freq="M"))
  444. expected = Series([x[0], x[1], y[0], y[1]], dtype="object")
  445. result = concat([x, y], ignore_index=True)
  446. tm.assert_series_equal(result, expected)
  447. assert result.dtype == "object"
  448. def test_concat_period_other_series2(self):
  449. # non-period
  450. x = Series(pd.PeriodIndex(["2015-11-01", "2015-12-01"], freq="D"))
  451. y = Series(DatetimeIndex(["2015-11-01", "2015-12-01"]))
  452. expected = Series([x[0], x[1], y[0], y[1]], dtype="object")
  453. result = concat([x, y], ignore_index=True)
  454. tm.assert_series_equal(result, expected)
  455. assert result.dtype == "object"
  456. def test_concat_period_other_series3(self):
  457. x = Series(pd.PeriodIndex(["2015-11-01", "2015-12-01"], freq="D"))
  458. y = Series(["A", "B"])
  459. expected = Series([x[0], x[1], y[0], y[1]], dtype="object")
  460. result = concat([x, y], ignore_index=True)
  461. tm.assert_series_equal(result, expected)
  462. assert result.dtype == "object"
  463. def test_concat_timedelta64_block():
  464. rng = to_timedelta(np.arange(10), unit="s")
  465. df = DataFrame({"time": rng})
  466. result = concat([df, df])
  467. tm.assert_frame_equal(result.iloc[:10], df)
  468. tm.assert_frame_equal(result.iloc[10:], df)
  469. def test_concat_multiindex_datetime_nat():
  470. # GH#44900
  471. left = DataFrame({"a": 1}, index=MultiIndex.from_tuples([(1, pd.NaT)]))
  472. right = DataFrame(
  473. {"b": 2}, index=MultiIndex.from_tuples([(1, pd.NaT), (2, pd.NaT)])
  474. )
  475. result = concat([left, right], axis="columns")
  476. expected = DataFrame(
  477. {"a": [1.0, np.nan], "b": 2}, MultiIndex.from_tuples([(1, pd.NaT), (2, pd.NaT)])
  478. )
  479. tm.assert_frame_equal(result, expected)
  480. def test_concat_float_datetime64(using_array_manager):
  481. # GH#32934
  482. df_time = DataFrame({"A": pd.array(["2000"], dtype="datetime64[ns]")})
  483. df_float = DataFrame({"A": pd.array([1.0], dtype="float64")})
  484. expected = DataFrame(
  485. {
  486. "A": [
  487. pd.array(["2000"], dtype="datetime64[ns]")[0],
  488. pd.array([1.0], dtype="float64")[0],
  489. ]
  490. },
  491. index=[0, 0],
  492. )
  493. result = concat([df_time, df_float])
  494. tm.assert_frame_equal(result, expected)
  495. expected = DataFrame({"A": pd.array([], dtype="object")})
  496. result = concat([df_time.iloc[:0], df_float.iloc[:0]])
  497. tm.assert_frame_equal(result, expected)
  498. expected = DataFrame({"A": pd.array([1.0], dtype="object")})
  499. result = concat([df_time.iloc[:0], df_float])
  500. tm.assert_frame_equal(result, expected)
  501. if not using_array_manager:
  502. expected = DataFrame({"A": pd.array(["2000"], dtype="datetime64[ns]")})
  503. msg = "The behavior of DataFrame concatenation with empty or all-NA entries"
  504. with tm.assert_produces_warning(FutureWarning, match=msg):
  505. result = concat([df_time, df_float.iloc[:0]])
  506. tm.assert_frame_equal(result, expected)
  507. else:
  508. expected = DataFrame({"A": pd.array(["2000"], dtype="datetime64[ns]")}).astype(
  509. {"A": "object"}
  510. )
  511. result = concat([df_time, df_float.iloc[:0]])
  512. tm.assert_frame_equal(result, expected)