创建具有唯一索引

时间:2018-01-20 15:30:16

标签: python pandas

我是否可以创建一个具有唯一索引的数据框,类似于在mysql中创建唯一键,如果我尝试添加重复索引,它将返回错误?

或者我是唯一的选择来创建if语句并在追加它之前检查数据框中的值吗?

编辑:

看来我的问题有点不清楚。对于唯一列,我的意思是我们不能在列中包含非唯一值。

使用

df.append(new_row, verify_integrity=True)

我们可以检查所有列,但是我们如何只检查一列或两列?

2 个答案:

答案 0 :(得分:4)

您可以使用df.append(..., verify_integrity=True)维护唯一的索引:

import numpy as np
import pandas as pd

df = pd.DataFrame(np.arange(12).reshape(3,4), columns=list('ABCD'))
dup_row = pd.DataFrame([[10,20,30,40]], columns=list('ABCD'), index=[1])
new_row = pd.DataFrame([[10,20,30,40]], columns=list('ABCD'), index=[9])

这成功地附加了一个新行(索引为9):

df.append(new_row, verify_integrity=True)
#     A   B   C   D
# 0   0   1   2   3
# 1   4   5   6   7
# 2   8   9  10  11
# 9  10  20  30  40

这会引发ValueError,因为1已经在索引中:

df.append(dup_row, verify_integrity=True)
# ValueError: Indexes have overlapping values: [1]

虽然上述方法可以确保唯一的索引,但我并不知道确保唯一索引的类似方法。从理论上讲,您可以转置DataFrame,附加verify_integrity=True然后再转置,但通常我不建议这样做,因为当列dtypes不完全相同时,转置可以改变dtypes。 (当列dtypes不完全相同时,转置的DataFrame会获得object dtype的列。转换到对象数组和从对象数组转换可能对性能不利。)

如果您需要唯一的行和列索引,那么可能更好的选择是stack您的DataFrame,以便所有唯一列索引级别成为行索引级别。然后,您可以在重新塑造的DataFrame上使用appendverify_integrity=True

答案 1 :(得分:0)

OP的后续问题:

  

使用df.append(new_row,verify_integrity = True),我们可以检查所有列,但是我们如何检查只有一两列   列?

要检查一列的唯一性,请说列名为value,可以尝试

df['value'].duplicated().any()

这将检查此列中是否有任何重复。如果重复,那么它不是唯一的。

如果有两列,比如C1C2,要检查是否存在重复的,我们仍然可以使用DataFrame.duplicated

df[["C1", "C2"]].duplicated()

它将检查行方式的唯一性。您可以再次使用any检查返回的值是否为True

如果有两列,比如C1C2,要检查每个列是否包含重复值,我们可以使用apply。

df[["C1", "C2"]].apply(lambda x: x.duplicated().any())

这会将函数应用于每一列。

注意

pd.DataFrame([[np.nan, np.nan],
              [ np.nan, np.nan]]).duplicated()

0    False
1     True
dtype: bool

np.nan也会被duplicated捕获。如果您想忽略np.nan,可以先尝试选择非纳米部分。