Python中的表重新排序覆盖了最后两行

时间:2019-07-05 13:30:55

标签: python

我正在尝试重新排列Python中CSV数据集的顺序,以允许我将其追加到另一个文件中。我有标题[a,b,c,d,e,f],需要更改为[b,c,f,e,d,a]。但是,我正在使用的for循环产生的标题按[b,c,a,e,e,a]的顺序排列。大概是因为我的索引正在更新中循环,但我不确定如何解决它。

请参见下面的代码:

def headings(file):
  correct_order = ["a", "b", "c", "d", "e", "f",]
  current_order = ["b", "c", "f", "e", "d", "a",]
  for i in range(0, len(current_order)):
    index = correct_order.index(current_order[i])
      for row in file:
        row.insert(index,row[i])
        row.pop(index+1)

我在做什么错了?

2 个答案:

答案 0 :(得分:1)

也许不是您要找的东西,但是您是否考虑过使用熊猫?

import pandas as pd

df = pd.read_csv(file)

correct_order = ["a", "b", "b", "d", "e", "f"]
df = df[correct_order]
df.to_csv(new_file)

答案 1 :(得分:0)

您正在使用两个不同的索引,icurrent_order中的位置,而index是您要放置它的位置。您还将列循环放在行循环之外,这可能会引起一些混乱。

组合row.insert(index,row[i])在位置row[i]上插入index的副本,该副本可能在i之前,也可能不在该位置。以下pop假定以前。一种更干净的方法是使用pop进行检索:

row.insert(index, row.pop(i))

这意味着pop返回了被删除的元素,然后将其重新插入到应该放置的位置,在row中从来没有重复。但是,这仍然不能为我们提供正确的顺序,因为i是按位置进行遍历的,而不关心是否刚刚插入的值;这是一个典型的例子,说明在迭代列表时如何对列表进行更改很麻烦。

我想到了另外两种方法:正向或反向排列到新列表中。

from_place = [current_order.index(k) for k in correct_order]
reordered_row = [row[k] for k in from_place]

to_place = [correct_order.index(k) for k in current_order]
reordered_row = [None] * len(correct_order)
for (i,v) in zip(to_place, row):
    reordered_row[i] = v

通常,使用名称比使用索引更可靠。例如,您可以使用csv.DictReader(f, current_order)然后阅读[row[k] for k in correct_order],或者最好完全跳过重新排序并仅使用键。