我为这个令人困惑的标题道歉,但这是一个令人困惑的问题。
我有一个包含多个列的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')
前两行按需要匹配的值对其进行排序,并在数据框中提取唯一的列表。熊猫可能不适合这个吗?
答案 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))]