test_nonunique_indexes.py 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477
  1. # -*- coding: utf-8 -*-
  2. from __future__ import print_function
  3. import numpy as np
  4. import pytest
  5. from pandas.compat import lrange, u
  6. import pandas as pd
  7. from pandas import DataFrame, MultiIndex, Series, date_range
  8. from pandas.tests.frame.common import TestData
  9. import pandas.util.testing as tm
  10. from pandas.util.testing import assert_frame_equal, assert_series_equal
  11. class TestDataFrameNonuniqueIndexes(TestData):
  12. def test_column_dups_operations(self):
  13. def check(result, expected=None):
  14. if expected is not None:
  15. assert_frame_equal(result, expected)
  16. result.dtypes
  17. str(result)
  18. # assignment
  19. # GH 3687
  20. arr = np.random.randn(3, 2)
  21. idx = lrange(2)
  22. df = DataFrame(arr, columns=['A', 'A'])
  23. df.columns = idx
  24. expected = DataFrame(arr, columns=idx)
  25. check(df, expected)
  26. idx = date_range('20130101', periods=4, freq='Q-NOV')
  27. df = DataFrame([[1, 1, 1, 5], [1, 1, 2, 5], [2, 1, 3, 5]],
  28. columns=['a', 'a', 'a', 'a'])
  29. df.columns = idx
  30. expected = DataFrame(
  31. [[1, 1, 1, 5], [1, 1, 2, 5], [2, 1, 3, 5]], columns=idx)
  32. check(df, expected)
  33. # insert
  34. df = DataFrame([[1, 1, 1, 5], [1, 1, 2, 5], [2, 1, 3, 5]],
  35. columns=['foo', 'bar', 'foo', 'hello'])
  36. df['string'] = 'bah'
  37. expected = DataFrame([[1, 1, 1, 5, 'bah'], [1, 1, 2, 5, 'bah'],
  38. [2, 1, 3, 5, 'bah']],
  39. columns=['foo', 'bar', 'foo', 'hello', 'string'])
  40. check(df, expected)
  41. with pytest.raises(ValueError, match='Length of value'):
  42. df.insert(0, 'AnotherColumn', range(len(df.index) - 1))
  43. # insert same dtype
  44. df['foo2'] = 3
  45. expected = DataFrame([[1, 1, 1, 5, 'bah', 3], [1, 1, 2, 5, 'bah', 3],
  46. [2, 1, 3, 5, 'bah', 3]],
  47. columns=['foo', 'bar', 'foo', 'hello',
  48. 'string', 'foo2'])
  49. check(df, expected)
  50. # set (non-dup)
  51. df['foo2'] = 4
  52. expected = DataFrame([[1, 1, 1, 5, 'bah', 4], [1, 1, 2, 5, 'bah', 4],
  53. [2, 1, 3, 5, 'bah', 4]],
  54. columns=['foo', 'bar', 'foo', 'hello',
  55. 'string', 'foo2'])
  56. check(df, expected)
  57. df['foo2'] = 3
  58. # delete (non dup)
  59. del df['bar']
  60. expected = DataFrame([[1, 1, 5, 'bah', 3], [1, 2, 5, 'bah', 3],
  61. [2, 3, 5, 'bah', 3]],
  62. columns=['foo', 'foo', 'hello', 'string', 'foo2'])
  63. check(df, expected)
  64. # try to delete again (its not consolidated)
  65. del df['hello']
  66. expected = DataFrame([[1, 1, 'bah', 3], [1, 2, 'bah', 3],
  67. [2, 3, 'bah', 3]],
  68. columns=['foo', 'foo', 'string', 'foo2'])
  69. check(df, expected)
  70. # consolidate
  71. df = df._consolidate()
  72. expected = DataFrame([[1, 1, 'bah', 3], [1, 2, 'bah', 3],
  73. [2, 3, 'bah', 3]],
  74. columns=['foo', 'foo', 'string', 'foo2'])
  75. check(df, expected)
  76. # insert
  77. df.insert(2, 'new_col', 5.)
  78. expected = DataFrame([[1, 1, 5., 'bah', 3], [1, 2, 5., 'bah', 3],
  79. [2, 3, 5., 'bah', 3]],
  80. columns=['foo', 'foo', 'new_col', 'string',
  81. 'foo2'])
  82. check(df, expected)
  83. # insert a dup
  84. with pytest.raises(ValueError, match='cannot insert'):
  85. df.insert(2, 'new_col', 4.)
  86. df.insert(2, 'new_col', 4., allow_duplicates=True)
  87. expected = DataFrame([[1, 1, 4., 5., 'bah', 3],
  88. [1, 2, 4., 5., 'bah', 3],
  89. [2, 3, 4., 5., 'bah', 3]],
  90. columns=['foo', 'foo', 'new_col',
  91. 'new_col', 'string', 'foo2'])
  92. check(df, expected)
  93. # delete (dup)
  94. del df['foo']
  95. expected = DataFrame([[4., 5., 'bah', 3], [4., 5., 'bah', 3],
  96. [4., 5., 'bah', 3]],
  97. columns=['new_col', 'new_col', 'string', 'foo2'])
  98. assert_frame_equal(df, expected)
  99. # dup across dtypes
  100. df = DataFrame([[1, 1, 1., 5], [1, 1, 2., 5], [2, 1, 3., 5]],
  101. columns=['foo', 'bar', 'foo', 'hello'])
  102. check(df)
  103. df['foo2'] = 7.
  104. expected = DataFrame([[1, 1, 1., 5, 7.], [1, 1, 2., 5, 7.],
  105. [2, 1, 3., 5, 7.]],
  106. columns=['foo', 'bar', 'foo', 'hello', 'foo2'])
  107. check(df, expected)
  108. result = df['foo']
  109. expected = DataFrame([[1, 1.], [1, 2.], [2, 3.]],
  110. columns=['foo', 'foo'])
  111. check(result, expected)
  112. # multiple replacements
  113. df['foo'] = 'string'
  114. expected = DataFrame([['string', 1, 'string', 5, 7.],
  115. ['string', 1, 'string', 5, 7.],
  116. ['string', 1, 'string', 5, 7.]],
  117. columns=['foo', 'bar', 'foo', 'hello', 'foo2'])
  118. check(df, expected)
  119. del df['foo']
  120. expected = DataFrame([[1, 5, 7.], [1, 5, 7.], [1, 5, 7.]], columns=[
  121. 'bar', 'hello', 'foo2'])
  122. check(df, expected)
  123. # values
  124. df = DataFrame([[1, 2.5], [3, 4.5]], index=[1, 2], columns=['x', 'x'])
  125. result = df.values
  126. expected = np.array([[1, 2.5], [3, 4.5]])
  127. assert (result == expected).all().all()
  128. # rename, GH 4403
  129. df4 = DataFrame(
  130. {'RT': [0.0454],
  131. 'TClose': [22.02],
  132. 'TExg': [0.0422]},
  133. index=MultiIndex.from_tuples([(600809, 20130331)],
  134. names=['STK_ID', 'RPT_Date']))
  135. df5 = DataFrame({'RPT_Date': [20120930, 20121231, 20130331],
  136. 'STK_ID': [600809] * 3,
  137. 'STK_Name': [u('饡驦'), u('饡驦'), u('饡驦')],
  138. 'TClose': [38.05, 41.66, 30.01]},
  139. index=MultiIndex.from_tuples(
  140. [(600809, 20120930),
  141. (600809, 20121231),
  142. (600809, 20130331)],
  143. names=['STK_ID', 'RPT_Date']))
  144. k = pd.merge(df4, df5, how='inner', left_index=True, right_index=True)
  145. result = k.rename(
  146. columns={'TClose_x': 'TClose', 'TClose_y': 'QT_Close'})
  147. str(result)
  148. result.dtypes
  149. expected = (DataFrame([[0.0454, 22.02, 0.0422, 20130331, 600809,
  150. u('饡驦'), 30.01]],
  151. columns=['RT', 'TClose', 'TExg',
  152. 'RPT_Date', 'STK_ID', 'STK_Name',
  153. 'QT_Close'])
  154. .set_index(['STK_ID', 'RPT_Date'], drop=False))
  155. assert_frame_equal(result, expected)
  156. # reindex is invalid!
  157. df = DataFrame([[1, 5, 7.], [1, 5, 7.], [1, 5, 7.]],
  158. columns=['bar', 'a', 'a'])
  159. pytest.raises(ValueError, df.reindex, columns=['bar'])
  160. pytest.raises(ValueError, df.reindex, columns=['bar', 'foo'])
  161. # drop
  162. df = DataFrame([[1, 5, 7.], [1, 5, 7.], [1, 5, 7.]],
  163. columns=['bar', 'a', 'a'])
  164. result = df.drop(['a'], axis=1)
  165. expected = DataFrame([[1], [1], [1]], columns=['bar'])
  166. check(result, expected)
  167. result = df.drop('a', axis=1)
  168. check(result, expected)
  169. # describe
  170. df = DataFrame([[1, 1, 1], [2, 2, 2], [3, 3, 3]],
  171. columns=['bar', 'a', 'a'], dtype='float64')
  172. result = df.describe()
  173. s = df.iloc[:, 0].describe()
  174. expected = pd.concat([s, s, s], keys=df.columns, axis=1)
  175. check(result, expected)
  176. # check column dups with index equal and not equal to df's index
  177. df = DataFrame(np.random.randn(5, 3), index=['a', 'b', 'c', 'd', 'e'],
  178. columns=['A', 'B', 'A'])
  179. for index in [df.index, pd.Index(list('edcba'))]:
  180. this_df = df.copy()
  181. expected_ser = pd.Series(index.values, index=this_df.index)
  182. expected_df = DataFrame({'A': expected_ser,
  183. 'B': this_df['B'],
  184. 'A': expected_ser},
  185. columns=['A', 'B', 'A'])
  186. this_df['A'] = index
  187. check(this_df, expected_df)
  188. # operations
  189. for op in ['__add__', '__mul__', '__sub__', '__truediv__']:
  190. df = DataFrame(dict(A=np.arange(10), B=np.random.rand(10)))
  191. expected = getattr(df, op)(df)
  192. expected.columns = ['A', 'A']
  193. df.columns = ['A', 'A']
  194. result = getattr(df, op)(df)
  195. check(result, expected)
  196. # multiple assignments that change dtypes
  197. # the location indexer is a slice
  198. # GH 6120
  199. df = DataFrame(np.random.randn(5, 2), columns=['that', 'that'])
  200. expected = DataFrame(1.0, index=range(5), columns=['that', 'that'])
  201. df['that'] = 1.0
  202. check(df, expected)
  203. df = DataFrame(np.random.rand(5, 2), columns=['that', 'that'])
  204. expected = DataFrame(1, index=range(5), columns=['that', 'that'])
  205. df['that'] = 1
  206. check(df, expected)
  207. def test_column_dups2(self):
  208. # drop buggy GH 6240
  209. df = DataFrame({'A': np.random.randn(5),
  210. 'B': np.random.randn(5),
  211. 'C': np.random.randn(5),
  212. 'D': ['a', 'b', 'c', 'd', 'e']})
  213. expected = df.take([0, 1, 1], axis=1)
  214. df2 = df.take([2, 0, 1, 2, 1], axis=1)
  215. result = df2.drop('C', axis=1)
  216. assert_frame_equal(result, expected)
  217. # dropna
  218. df = DataFrame({'A': np.random.randn(5),
  219. 'B': np.random.randn(5),
  220. 'C': np.random.randn(5),
  221. 'D': ['a', 'b', 'c', 'd', 'e']})
  222. df.iloc[2, [0, 1, 2]] = np.nan
  223. df.iloc[0, 0] = np.nan
  224. df.iloc[1, 1] = np.nan
  225. df.iloc[:, 3] = np.nan
  226. expected = df.dropna(subset=['A', 'B', 'C'], how='all')
  227. expected.columns = ['A', 'A', 'B', 'C']
  228. df.columns = ['A', 'A', 'B', 'C']
  229. result = df.dropna(subset=['A', 'C'], how='all')
  230. assert_frame_equal(result, expected)
  231. def test_column_dups_indexing(self):
  232. def check(result, expected=None):
  233. if expected is not None:
  234. assert_frame_equal(result, expected)
  235. result.dtypes
  236. str(result)
  237. # boolean indexing
  238. # GH 4879
  239. dups = ['A', 'A', 'C', 'D']
  240. df = DataFrame(np.arange(12).reshape(3, 4), columns=[
  241. 'A', 'B', 'C', 'D'], dtype='float64')
  242. expected = df[df.C > 6]
  243. expected.columns = dups
  244. df = DataFrame(np.arange(12).reshape(3, 4),
  245. columns=dups, dtype='float64')
  246. result = df[df.C > 6]
  247. check(result, expected)
  248. # where
  249. df = DataFrame(np.arange(12).reshape(3, 4), columns=[
  250. 'A', 'B', 'C', 'D'], dtype='float64')
  251. expected = df[df > 6]
  252. expected.columns = dups
  253. df = DataFrame(np.arange(12).reshape(3, 4),
  254. columns=dups, dtype='float64')
  255. result = df[df > 6]
  256. check(result, expected)
  257. # boolean with the duplicate raises
  258. df = DataFrame(np.arange(12).reshape(3, 4),
  259. columns=dups, dtype='float64')
  260. pytest.raises(ValueError, lambda: df[df.A > 6])
  261. # dup aligining operations should work
  262. # GH 5185
  263. df1 = DataFrame([1, 2, 3, 4, 5], index=[1, 2, 1, 2, 3])
  264. df2 = DataFrame([1, 2, 3], index=[1, 2, 3])
  265. expected = DataFrame([0, 2, 0, 2, 2], index=[1, 1, 2, 2, 3])
  266. result = df1.sub(df2)
  267. assert_frame_equal(result, expected)
  268. # equality
  269. df1 = DataFrame([[1, 2], [2, np.nan], [3, 4], [4, 4]],
  270. columns=['A', 'B'])
  271. df2 = DataFrame([[0, 1], [2, 4], [2, np.nan], [4, 5]],
  272. columns=['A', 'A'])
  273. # not-comparing like-labelled
  274. pytest.raises(ValueError, lambda: df1 == df2)
  275. df1r = df1.reindex_like(df2)
  276. result = df1r == df2
  277. expected = DataFrame([[False, True], [True, False], [False, False], [
  278. True, False]], columns=['A', 'A'])
  279. assert_frame_equal(result, expected)
  280. # mixed column selection
  281. # GH 5639
  282. dfbool = DataFrame({'one': Series([True, True, False],
  283. index=['a', 'b', 'c']),
  284. 'two': Series([False, False, True, False],
  285. index=['a', 'b', 'c', 'd']),
  286. 'three': Series([False, True, True, True],
  287. index=['a', 'b', 'c', 'd'])})
  288. expected = pd.concat(
  289. [dfbool['one'], dfbool['three'], dfbool['one']], axis=1)
  290. result = dfbool[['one', 'three', 'one']]
  291. check(result, expected)
  292. # multi-axis dups
  293. # GH 6121
  294. df = DataFrame(np.arange(25.).reshape(5, 5),
  295. index=['a', 'b', 'c', 'd', 'e'],
  296. columns=['A', 'B', 'C', 'D', 'E'])
  297. z = df[['A', 'C', 'A']].copy()
  298. expected = z.loc[['a', 'c', 'a']]
  299. df = DataFrame(np.arange(25.).reshape(5, 5),
  300. index=['a', 'b', 'c', 'd', 'e'],
  301. columns=['A', 'B', 'C', 'D', 'E'])
  302. z = df[['A', 'C', 'A']]
  303. result = z.loc[['a', 'c', 'a']]
  304. check(result, expected)
  305. def test_column_dups_indexing2(self):
  306. # GH 8363
  307. # datetime ops with a non-unique index
  308. df = DataFrame({'A': np.arange(5, dtype='int64'),
  309. 'B': np.arange(1, 6, dtype='int64')},
  310. index=[2, 2, 3, 3, 4])
  311. result = df.B - df.A
  312. expected = Series(1, index=[2, 2, 3, 3, 4])
  313. assert_series_equal(result, expected)
  314. df = DataFrame({'A': date_range('20130101', periods=5),
  315. 'B': date_range('20130101 09:00:00', periods=5)},
  316. index=[2, 2, 3, 3, 4])
  317. result = df.B - df.A
  318. expected = Series(pd.Timedelta('9 hours'), index=[2, 2, 3, 3, 4])
  319. assert_series_equal(result, expected)
  320. def test_columns_with_dups(self):
  321. # GH 3468 related
  322. # basic
  323. df = DataFrame([[1, 2]], columns=['a', 'a'])
  324. df.columns = ['a', 'a.1']
  325. str(df)
  326. expected = DataFrame([[1, 2]], columns=['a', 'a.1'])
  327. assert_frame_equal(df, expected)
  328. df = DataFrame([[1, 2, 3]], columns=['b', 'a', 'a'])
  329. df.columns = ['b', 'a', 'a.1']
  330. str(df)
  331. expected = DataFrame([[1, 2, 3]], columns=['b', 'a', 'a.1'])
  332. assert_frame_equal(df, expected)
  333. # with a dup index
  334. df = DataFrame([[1, 2]], columns=['a', 'a'])
  335. df.columns = ['b', 'b']
  336. str(df)
  337. expected = DataFrame([[1, 2]], columns=['b', 'b'])
  338. assert_frame_equal(df, expected)
  339. # multi-dtype
  340. df = DataFrame([[1, 2, 1., 2., 3., 'foo', 'bar']],
  341. columns=['a', 'a', 'b', 'b', 'd', 'c', 'c'])
  342. df.columns = list('ABCDEFG')
  343. str(df)
  344. expected = DataFrame(
  345. [[1, 2, 1., 2., 3., 'foo', 'bar']], columns=list('ABCDEFG'))
  346. assert_frame_equal(df, expected)
  347. # this is an error because we cannot disambiguate the dup columns
  348. pytest.raises(Exception, lambda x: DataFrame(
  349. [[1, 2, 'foo', 'bar']], columns=['a', 'a', 'a', 'a']))
  350. # dups across blocks
  351. df_float = DataFrame(np.random.randn(10, 3), dtype='float64')
  352. df_int = DataFrame(np.random.randn(10, 3), dtype='int64')
  353. df_bool = DataFrame(True, index=df_float.index,
  354. columns=df_float.columns)
  355. df_object = DataFrame('foo', index=df_float.index,
  356. columns=df_float.columns)
  357. df_dt = DataFrame(pd.Timestamp('20010101'),
  358. index=df_float.index,
  359. columns=df_float.columns)
  360. df = pd.concat([df_float, df_int, df_bool, df_object, df_dt], axis=1)
  361. assert len(df._data._blknos) == len(df.columns)
  362. assert len(df._data._blklocs) == len(df.columns)
  363. # testing iloc
  364. for i in range(len(df.columns)):
  365. df.iloc[:, i]
  366. # dup columns across dtype GH 2079/2194
  367. vals = [[1, -1, 2.], [2, -2, 3.]]
  368. rs = DataFrame(vals, columns=['A', 'A', 'B'])
  369. xp = DataFrame(vals)
  370. xp.columns = ['A', 'A', 'B']
  371. assert_frame_equal(rs, xp)
  372. def test_values_duplicates(self):
  373. df = DataFrame([[1, 2, 'a', 'b'],
  374. [1, 2, 'a', 'b']],
  375. columns=['one', 'one', 'two', 'two'])
  376. result = df.values
  377. expected = np.array([[1, 2, 'a', 'b'], [1, 2, 'a', 'b']],
  378. dtype=object)
  379. tm.assert_numpy_array_equal(result, expected)
  380. def test_set_value_by_index(self):
  381. # See gh-12344
  382. df = DataFrame(np.arange(9).reshape(3, 3).T)
  383. df.columns = list('AAA')
  384. expected = df.iloc[:, 2]
  385. df.iloc[:, 0] = 3
  386. assert_series_equal(df.iloc[:, 2], expected)
  387. df = DataFrame(np.arange(9).reshape(3, 3).T)
  388. df.columns = [2, float(2), str(2)]
  389. expected = df.iloc[:, 1]
  390. df.iloc[:, 0] = 3
  391. assert_series_equal(df.iloc[:, 1], expected)
  392. def test_insert_with_columns_dups(self):
  393. # GH 14291
  394. df = pd.DataFrame()
  395. df.insert(0, 'A', ['g', 'h', 'i'], allow_duplicates=True)
  396. df.insert(0, 'A', ['d', 'e', 'f'], allow_duplicates=True)
  397. df.insert(0, 'A', ['a', 'b', 'c'], allow_duplicates=True)
  398. exp = pd.DataFrame([['a', 'd', 'g'], ['b', 'e', 'h'],
  399. ['c', 'f', 'i']], columns=['A', 'A', 'A'])
  400. assert_frame_equal(df, exp)