我需要导入和转换xlsx文件。它们是以宽格式编写的,我需要从每一行复制一些单元格信息,并将其与所有其他行的信息配对:
[Edit:更改格式以表示更复杂的要求]
源格式
| 识别码|属性|活动1名称|活动1时间戳|活动2名称|活动2时间戳|
| - -|- -|- -|- -|- -|- -|
| 一个|A级|一种|1月1日22时00分|B| 2.1.22上午10时05分|
| 2个|B|一种|1月1日22时03分|B| 5.1.22 20时16分|
目标格式
| 识别码|属性|活动|时间戳记|
| - -|- -|- -|- -|
| 一个|A级|一种|1月1日22时00分|
| 一个|A级|B| 2.1.22上午10时05分|
| 2个|B|一种|1月1日22时03分|
| 2个|B| B| 5.1.22 20时16分|
下面的代码可以很好地转换数据,但是转换过程非常非常慢:
def transform(data_in):
data = pd.DataFrame(columns=columns)
# Determine number of processes entered in a single row of the original file
steps_per_row = int((data_in.shape[1] - (len(columns) - 2)) / len(process_matching) + 1)
data_in = data_in.to_dict("records") # Convert to dict for speed optimization
for row_dict in tqdm(data_in): # Iterate over each row of the original file
new_row = {}
# Set common columns for each process step
for column in column_matching:
new_row[column] = row_dict[column_matching[column]]
for step in range(0, steps_per_row):
rep = str(step+1) if step > 0 else ""
# Iterate for as many times as there are process steps in one row of the original file and
# set specific columns for each process step, keeping common column values identical for current row
for column in process_matching:
new_row[column] = row_dict[process_matching[column]+rep]
data = data.append(new_row, ignore_index=True) # append dict of new_row to existing data
data.index.name = "SortKey"
data[timestamp].replace(r'.000', '', regex=True, inplace=True) # Remove trailing zeros from timestamp # TODO check if works as intended
data.replace(r'^\s*$', float('NaN'), regex=True, inplace=True) # Replace cells with only spaces with nan
data.dropna(axis=0, how="all", inplace=True) # Remove empty rows
data.dropna(axis=1, how="all", inplace=True) # Remove empty columns
data.dropna(axis=0, subset=[timestamp], inplace=True) # Drop rows with empty Timestamp
data.fillna('', inplace=True) # Replace NaN values with empty cells
return data
显然,遍历每行甚至每列根本不是正确使用Pandas的方法,但我看不出这种转换如何可以矢量化。
我试过使用并行化(modin),也试过使用dict,但它不起作用/没有帮助。脚本的其余部分实际上只是打开和保存文件,所以问题就在这里。
如果有任何关于如何提高速度的想法,我将非常感激!
2条答案
按热度按时间2w3kk1z51#
df.melt
函数应该能够更快地执行这种类型的操作。编辑以解决修改后的问题将
df.melt
与df.pivot
操作组合。8ehkhllq2#
使用pd.melt,正如@Pantelis所建议的,我能够极大地加快这个转换,这是令人难以置信的。以前,一个大约13 k行的文件在一个全新的ThinkPad X1上需要4-5个小时,现在只需要不到2分钟!这是一个150倍的速度,真是太棒了。:)
下面是我的新代码,如果有人有类似的数据结构,可以作为灵感/参考: