如果重复

时间:2018-01-04 17:16:49

标签: python pandas dataframe

我为这个令人困惑的标题道歉,但这是一个令人困惑的问题。

我有一个包含多个列的CSV文件,如下例所示:

header_a | header_b | header_c | header_d
  abc         1         data1      data2
  abc         1         data3      data4
  abc         2         data5      data6
  abc         2         data7      data8
  abc         3         data9      data10

我需要一个能够将此数据转换为以下格式的脚本:

header_a | header_b | header_c | header_d
  abc         1         data1      data2    data3      data4      
  abc         2         data5      data6    data7      data8      
  abc         3         data9      data10

我不关心标题,因为我可以有多个条目。但简而言之,只要header_b中的值匹配,我就需要在行中将其后面的所有值附加到数据框中的第一个实例。

我有一个关于我如何处理这个问题的骨架,但我被卡住了:

dd.sort_values('Purchase Order #', inplace=True)
values = dd['Purchase Order #'].unique().tolist()

for x in values:
    header_flag = False
    for row in dd['Purchase Order #']:
        if x == row:
            if header_flag == False:
                #This is the first purchase order, copy entire line
                print(row.tolist())
                #set the flag to True
                header_flag = True
            else:
                #We already have the first header, only copy next 5
                print('Else Block')
        else:
            #Do nothing
            print('False')

前两行按需要匹配的值对其进行排序,并在数据框中提取唯一的列表。熊猫可能不适合这个吗?

2 个答案:

答案 0 :(得分:1)

我还没有与熊猫合作,但我能够在没有它的情况下实现这一目标。假设标题和第一列' abc'是静态的。为简单起见,我将省略标题,因为您只关心组合数据。

我的方法是将header_b的值作为键,其余的是值列表。

>>> header_b = {}
>>> with open ('testfiles/test.csv') as csvfile:
...     next (csvfile)  # Skip headers
...     reader = csv.reader (csvfile)
...     for row in reader:
...         header_b.setdefault (row[1], [])  #  If header_b key is not in dictionary, add it
...         data = [row [0], row [2], row [3]]  # Create a list of data points
...         if row [0] in header_b [row [1]]:
...             data = [row [2], row [3]]  # If header_a is already in the list, skip
...         header_b [row [1]].extend (data)  # Or header_b [row [1]] += data
... 
>>> for key, values in header_b.items ():
...     string = ' '.join (values [1:])
...     print (values [0], key, string)
...

abc 2 data5 data6 data7 data8
abc 1 data1 data2 data3 data4
abc 3 data9 data10

由于未对字典进行排序,因此未输出输出。如果您希望按键排序,可以使用OrderedDict。

>>> sorted_keys = OrderedDict (sorted (header_b.items ()))
>>> for key, values in sorted_keys.items ():
...     string = ' '.join (values [1:])
...     print (values [0], key, string)
... 

abc 1 data1 data2 data3 data4
abc 2 data5 data6 data7 data8
abc 3 data9 data10

答案 1 :(得分:0)

Groupby可以帮到你需要的地方。如果数据类型是字符串,则可以将其单行显示为:

grp_sum = df.groupby('header_b').sum()

当然,这不会添加新列,但如果您有标准字符串模式,则可以拆分列。在您的示例中,

def splitter(x):
    return (x[:5], x[5:])

split_cols = [x for x in zip(*grp_sum['header_c'].apply(splitter))]