将列附加到填充了相同布尔值的数据框中的最佳方法是什么

时间:2018-09-27 08:08:15

标签: python pandas csv dataframe append

给出如下数据框:

df1 = pd.DataFrame({'A': ['A0', 'A1', 'A2'],
                'B': ['B0', 'B1', 'B2'],
                'C': ['C0', 'C1', 'C2']},
                index=[0, 1, 2])

   A   B   C
0  A0  B0  C0
1  A1  B1  C1
2  A2  B2  C2 

我想添加以值False初始化的列'D'。列“ D”将在以后处理数据框时使用:

    A   B   C      D
0  A0  B0  C0  False
1  A1  B1  C1  False
2  A2  B2  C2  False

我根据df1索引生成了False值列表,并用它创建了df2,然后将其与df1串联:

Dlist = [False for item in list(range(len(df1.index)))]
d = {'D':Dlist}
df2 = pd.DataFrame(d, index = df1.index)
result = pd.concat([df1, df2], axis=1, join_axes=[df1.index])

几个问题: 第一行中的列表理解是否需要参与其中? 我尝试了以下操作,认为'df1.index'是类似列表的。没用。

Dlist = [False for item in df1.index]

更广泛地说,是否有更好的方法可用于数据框操作? 如果我要处理的是包含df1数据的“ csv”文件,则可以在生成数据帧之前轻松地在文件中添加“ D”。

就哲学而言,在处理数据时是否不可避免地要修改数据帧或它们来自的“ csv”文件?当处理非常大的文件中的数据时,这当然不是一件好事。

1 个答案:

答案 0 :(得分:2)

您可以只使用基于索引的分配:

In [16]: df1 = pd.DataFrame({'A': ['A0', 'A1', 'A2'],
    ...:                 'B': ['B0', 'B1', 'B2'],
    ...:                 'C': ['C0', 'C1', 'C2']},
    ...:                 index=[0, 1, 2])

In [17]: df1
Out[17]:
    A   B   C
0  A0  B0  C0
1  A1  B1  C1
2  A2  B2  C2

In [18]: df1['D'] = False

In [19]: df1
Out[19]:
    A   B   C      D
0  A0  B0  C0  False
1  A1  B1  C1  False
2  A2  B2  C2  False

如果您不想修改原始数据,也可以使用.assign来返回新的数据帧:

In [20]: df1 = pd.DataFrame({'A': ['A0', 'A1', 'A2'],
    ...:                 'B': ['B0', 'B1', 'B2'],
    ...:                 'C': ['C0', 'C1', 'C2']},
    ...:                 index=[0, 1, 2])

In [21]: df1
Out[21]:
    A   B   C
0  A0  B0  C0
1  A1  B1  C1
2  A2  B2  C2

In [22]: df1.assign(D=False)
Out[22]:
    A   B   C      D
0  A0  B0  C0  False
1  A1  B1  C1  False
2  A2  B2  C2  False

In [23]: df1
Out[23]:
    A   B   C
0  A0  B0  C0
1  A1  B1  C1
2  A2  B2  C2

在这里使用pd.concat确实没有用,您只需分配列表即可!无论哪种方式,它都仍然慢得多:

In [44]: import timeit

In [45]: setup = 'import pandas as pd; df = pd.DataFrame({"a":list(range(100000))})'

In [46]: lstcomp = "df['D'] = [False for item in range(len(df.index))]"

In [47]: assgnmt = "df['D'] = False"

In [48]: timeit.timeit(lstcomp, setup, number=100)
Out[48]: 0.6879564090049826

In [49]: timeit.timeit(assgnmt, setup, number=100)
Out[49]: 0.008814844011794776

对于您的列表理解,这不是必需的,但肯定过于复杂。您说您尝试遍历索引,但是“它没有用”,但是您从未解释过如何没用。它对我有用:

In [24]: [False for item in list(range(len(df1.index)))]
Out[24]: [False, False, False]

In [25]: [False for item in df1.index]
Out[25]: [False, False, False]

请注意,您的计算机效率很低,因为它在list对象上调用range,这会创建一个完整的列表,而不是利用range的固定内存行为(不是提到重复两次)。