背景:包含映射的Excel表格。大致外观如下:
Req1 Req2 Req3 ..... Req10 A B A B A B A BId Text 1 abc x x x2 def x3 ghi x4 jkl x5 mno x
编辑:Excel文件的截图
问题:如何仅提取标记有’x’的列?也就是说,Req3列将不被考虑。
挑战:列标题在原始Excel中是合并的单元格,并且与“Text”列处于不同的层次。
已尝试:研究了.groupby()函数和for循环。但不确定如何继续使用这些选项(如果它们适用的话)。
想法:(更新)将文件拆分为两个独立的数据框(Text + Reqs)。删除导致标题位置差异的行。然后重新连接独立的数据框——但如何操作?
已经将整个Excel文件转换为.csv并在jupyternotebooks代码中作为数据框打开。也可以提取单独的列,但由于列标题之间的差异,无法将“ReqN”包含在数据框中。
预期结果:包含“Text”列和出现“x”的“ReqN”列的Pandas数据框。(不关心是A还是B被标记。)
下一步:(如果与上述解决方案相关)以某种方式将“Text”+对应的“ReqN”存储为csv文件。
我是Python和Pandas的新手。非常希望能得到一些代码指导。在SO上找到了几个例子,但它们在某些地方或多或少都有不足之处。
回答:
最初我希望通过减少不必要的数据来减小我的.csv文件的大小,然后再将其输入代码中。然而,对于我的文件来说,内存或速度不会成为问题。而且由于预先剪切的方法给我带来了太多错误,我尝试了另一种方法。
进一步解决了问题中描述的“想法”。下面发布带有详细信息的代码。这可能是一个较长的方法,但对于像我这样的新手来说,它解决了问题。
#导入必要的库import pandas as pdimport numpy as npimport xlrdimport csvimport openpyxlfrom openpyxl import load_workbook #将Excel转换为.csvdef csv_from_excel(): wb = xlrd.open_workbook(r"\...\Data Docs\DATA_FILE.xlsm") ws = wb.sheet_by_name('Index') csv_train_data_1 = open('csv_train_data_1.csv', 'w', encoding='utf8') wr = csv.writer(csv_train_data_1, quoting=csv.QUOTE_ALL) for rownum in range(ws.nrows): wr.writerow(ws.row_values(rownum)) csv_train_data_1.close()csv_from_excel()#计划稍后使用maxRowsfileName = r"\...\Data Docs\DATA_FILE.xlsm"wb2 = load_workbook(fileName)ws4 = wb2["Index"]maxRows = ws4.max_rowprint(maxRows)#将CSV转换为数据框df = pd.read_csv("csv_train_data_1.csv") #创建新的DF,删除不必要的行df = pd.read_csv("csv_train_data_1.csv", header = 1)df2 = df.drop([0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14])#剪切并合并数据框的部分以满足我的需求cols = [1]useful_df_1 = df[df.columns[cols]]useful_df_2 = df[df2.columns[25:73]] useful_df_3 = useful_df_1.join([useful_df_2])useful_df = useful_df_3.drop([0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14])#重命名一列result_new = useful_df.rename(columns={"Unnamed: 1": "Specification no."})#用空字符串替换所有NaN值以清理数据import numpy as npresult_clean= result_new.replace(np.nan, '', regex=True)result_clean.head(maxRows)
最后
#将文件导出为.csv到本地文件夹export_csv = result_clean.to_csv(r'\...\Data\export_dataframe.csv', index = None, header=True)
这是最终结果。那些Unnamed (n)列是问题中示例数据中的B
列。显然,包含标题的列包括A
列。
我的数据相当大,有几百列和行。Pandas数据框默认在窗口中显示的行和列数量是固定的。要调整这些值以适应您的数据集,可以使用以下代码:
import pandas as pddef start(): options = { 'display': { 'max_columns': None, 'max_colwidth': 25, 'expand_frame_repr': False, # 不换页显示 'max_rows': 85, 'max_seq_items': 50, # 打印序列的最大长度 'precision': 4, 'show_dimensions': False }, 'mode': { 'chained_assignment': None # 控制SettingWithCopyWarning } } for category, option in options.items(): for op, value in option.items(): pd.set_option(f'{category}.{op}', value) # Python 3.6+if __name__ == '__main__': start() del start # 清理解释器中的命名空间
希望这对寻找解决方案的人有所帮助。由于数据不是我的,不能在公共论坛上发布,因此我为无法分享更多细节表示歉意。