使用 Pandas 在 Jupyter Notebook 中过滤 Excel 文档数据
Posted
技术标签:
【中文标题】使用 Pandas 在 Jupyter Notebook 中过滤 Excel 文档数据【英文标题】:Filtering Excel Document Data In Jupyter Notebook Using Pandas 【发布时间】:2020-04-20 15:56:32 【问题描述】:我有一个代码过滤数据,我不想使用 Pandas 从 Excel 文档中显示 在 Jupyter 笔记本中。它适用于英国皇家空军历史飞机展示团队,2009 年的出场时间表。
这是我的 Python 代码:-
import pandas as pd
xls = pd.ExcelFile(r'C:\Users\Edward\Desktop\BBMF Schedules And Master Forum Thread Texts\BBMF Display Schedule 2009.xls')
data = pd.read_excel(xls, sheet_name="Sheet1")
pd.options.display.max_rows = 1000
df = pd.DataFrame(data, columns= ['Venue','A/C','DISPLAY/','Date','BID'])
df[(df['Venue'].str.contains('[a-zA-Z]') & (df['DISPLAY/'].str.contains('DISPLAY') & df['A/C'].str.contains("DHS|DAK|HS|SPIT")) & (df['A/C'] != 'LHS') & (df['A/C'] != 'LANC'))]
当 BID 列中的数值与下一行的 BID 列中的值相同时,我不确定要键入什么内容来过滤数据。此外,仅当 A/C 列中的一架飞机,且上下 BID 列中的数值相同时,才为 DAK,并且排除该原则,仅当 A/ C 列显示 DHS 有人可以告诉我,我应该在我的 Python 代码中添加什么来启用它,如果有人可以的话,将不胜感激。
也以过滤后的数据为例,我想:-
输出:
145 SCARBOROUGH DAK DISPLAY 2008-05-25 00:00:00 610
150 SCARBOROUGH SPIT DISPLAY 2008-05-25 00:00:00 610
更改为显示以下内容,即将两行合并在一起:-
输出:
SCARBOROUGH DS DISPLAY 2008-05-25 00:00:00 610
和
输出:
173 TARRANT RUSHDEN HS DISPLAY NaN 132
174 TARRANT RUSHDEN DAK DISPLAY NaN 132
改为显示:-
输出:
TARRANT RUSHDEN DHS DISPLAY NaN 132
我的意思是更改为显示,对于所有这些事件,
不只是这两个场地。
这是我的输出数据示例:-
Venue A/C DISPLAY/ Date BID
25 SHUTTLEWORTH DAK DISPLAY NaN 529
55 KEMBLE DAK DISPLAY NaN 461
69 NORTHWICH SPIT DISPLAY 2008-05-10 00:00:00 514
72 POCKLINGTON SPIT DISPLAY 2009-05-10 00:00:00 821
75 BERLIN DAK DISPLAY 2008-05-12 00:00:00 587
78 MILDENHALL SPIT DISPLAY 2009-05-15 00:00:00 920
93 DUXFORD HS DISPLAY NaN 611
103 CRANWELL HS DISPLAY 2008-05-20 00:00:00 44
145 SCARBOROUGH DAK DISPLAY 2008-05-25 00:00:00 610
150 SCARBOROUGH SPIT DISPLAY 2008-05-25 00:00:00 610
151 CORBRIDGE SPIT DISPLAY NaN 353
167 BRIDGEND-CNX SPIT DISPLAY 2008-05-31 00:00:00 527
173 TARRANT RUSHDEN HS DISPLAY NaN 132
174 TARRANT RUSHDEN DAK DISPLAY NaN 132
179 NORTHOLT SPIT DISPLAY 2009-06-05 00:00:00 870
214 BRIZE NORTON HS DISPLAY NaN 939
218 ROPLEY HS DISPLAY 2008-06-13 00:00:00 355
223 THWAITES HS DISPLAY NaN 364
231 ROPLEY HS DISPLAY NaN 355
240 COSFORD HS DISPLAY 2008-06-14 00:00:00 667
241 QUORN HS DISPLAY NaN 314
244 COSFORD DAK DISPLAY 2008-06-14 00:00:00 NaN
260 REDHILL SPIT DISPLAY NaN 686
269 KEMBLE DAK DISPLAY NaN 316
270 KEMBLE HS DISPLAY NaN 316
280 KEMBLE SPIT DISPLAY 2008-06-21 00:00:00 316
285 KEMBLE DAK DISPLAY 2008-06-21 00:00:00 316
这是网站链接,指向 .xls,即 Excel 文档文件:-
http://web.archive.org/web/20090804234934/http://www.raf.mod.uk/bbmf/rafcms/mediafiles/F0ED6EA8_1143_EC82_2E4534A1036AA506.xls
您显然需要将我的 Python 代码中的以下内容更改为您所称的 .xls 文件。以及在您的计算机上保存它的路径:-
xls = pd.ExcelFile(r'C:\Users\Edward\Desktop\BBMF Schedules And Master Forum Thread Texts\BBMF Display Schedule 2009.xls')
我已将代码的结尾位更改为:-
selected = df.loc[df['A/C'] == 'DS', 'DH', 'DHS']
groupby_venue_date = selected.groupby(['Venue', 'BID', 'DISPLAY/'])
aircraft = groupby_venue_date['A/C std'].apply(''.join).rename('Aircraft-combined')
print(aircraft.shape)
pd.DataFrame(aircraft)
但是得到一个 :- IndexingError: Too many indexers 消息,当我运行代码时,这是什么意思?是什么导致了错误法案?
这是我目前在 2020 年 1 月 2 日运行的代码:-
import pandas as pd
xls = pd.ExcelFile(r'C:\Users\Edward\Desktop\BBMF Schedules And Master Forum Thread Texts\BBMF Display Schedule 2009.xls')
data = pd.read_excel(xls, sheet_name="Sheet1")
pd.options.display.max_rows = 1000
df = pd.DataFrame(data, columns= ['Venue','A/C','DISPLAY/','Date','BID'])
#df[(df['Venue'].str.contains('[a-zA-Z]') & (df['DISPLAY/'].str.contains('DISPLAY') & df['A/C'].str.contains("DHS|DAK|HS|SPIT")) & (df['A/C'] != 'LHS') & (df['A/C'] != 'LANC'))]
df["Date"].fillna("No Date", inplace = True)
df['A/C'].unique().tolist()
rename_map =
'DAK': 'D',
'SPIT': 'S',
'LANC': 'L',
'HURRI': 'H',
'PARA': 'P'
df['A/C std'] = df['A/C'].replace(rename_map)
print(df['A/C std'].unique().tolist())
#selected = df.loc[df['A/C'] == 'DS', 'DH', 'DHS']
selected = df.loc[df['DISPLAY/'] == 'DISPLAY']
groupby_venue_date = selected.groupby(['Venue', 'BID', 'Date', 'DISPLAY/'])
aircraft = groupby_venue_date['A/C std'].apply(''.join).rename('Aircraft-combined')
print(aircraft.shape)
pd.DataFrame(aircraft)
【问题讨论】:
听起来你想删除一些相同的重复项,除了'A/C'
列。那正确吗?但是合并后出现在该列中的替换值'DS'
和'DHS'
的逻辑是什么?
另外,您能否提供输入数据的样本?可能是 csv 文件的一部分或 df
的一部分。然后我们可以运行你的脚本来看看发生了什么。
你几乎正确的比尔,我实际上想保留相同的副本,除了“A/C”列。回答您的另一点,DS 代表 Dakota 和 Spitfire。 DHS 代表 Dakota Spitfire 和 Hurricane。
要我提供网站链接到 xls 文件,以便下载吗?
嗨,比尔,这是指向 .XLS 文件(即 Excel 文档文件)的网站链接:- web.archive.org/web/20090804234934/http://www.raf.mod.uk/bbmf/…
【参考方案1】:
我不确定我是否完全理解您想要做什么,但我会尝试通过提供一些技术来帮助您解决问题。
例如,获取列的唯一值列表:
df['A/C'].unique().tolist()
[nan, 'L', 'S', 'H', 'LHS', 'LANC', 'DAK', 'SPIT', 'HS', 'HURRI', 'PARA', 'LSSD', 'LSS', 'SS', 'LH', 'DH', 'DHS', 'SSSHH']
部分问题似乎在于处理这些由不同飞机组合而成的速记条目。例如。你说'DHS'
代表达科他、喷火战斗机和飓风。在尝试合并行之前先处理这些非标准值可能会更好。一种方法是使用字典替换所有非标准值。
例如
rename_map =
'DAK': 'D',
'SPIT': 'S',
'LANC': 'L',
'HURRI': 'H',
'PARA': 'P'
df['A/C std'] = df['A/C'].replace(rename_map)
print(df['A/C std'].unique().tolist())
[nan, 'L', 'S', 'H', 'LHS', 'D', 'HS', 'P', 'LSSD', 'LSS', 'SS', 'LH', 'DH', 'DHS', 'SSSHH']
然后你可以做任何你想做的事。例如,选择数据的一个子集:
selected = df.loc[df['DISPLAY/'] == 'DISPLAY']
assert selected.shape == (202, 6)
然后按选定的列对行进行分组,并使用字符串连接方法连接飞机代码:
groupby_venue_date = selected.groupby(['Venue', 'Date'])
aircraft = groupby_venue_date['A/C std'].apply(''.join).rename('Aircraft-combined')
assert aircraft.index.duplicated().sum() == 0
print(aircraft.shape)
print(aircraft.head())
(89,)
Venue Date
AUDLEM 2008-07-26 S
AYLSHAM 2008-08-31 LHS
BEAULIEU 2008-05-25 H
BELTRING 2008-07-26 L
BENSON 2008-08-27 LHS
Name: Aircraft-combined, dtype: object
部分值已加入:
print(aircraft.unique().tolist())
['S', 'LHS', 'H', 'L', 'D', 'HS', 'HSD', 'SLH', 'DHS', 'SD', 'SSSHH', 'LH', 'DS', 'DH', 'HSL']
更新
您可以通过制作函数并使用apply
方法对这些代码进行其他操作。
例如sorting the string 或removing duplicated characters(也恰好对它们进行排序)。
def sorted_string(s):
return ''.join(sorted(s))
def remove_duplicate_chars(s):
return ''.join(set(s))
aircraft = aircraft.apply(remove_duplicate_chars)
print(aircraft.unique().tolist())
['S', 'LHS', 'H', 'L', 'D', 'HS', 'DHS', 'DS', 'LH', 'DH']
【讨论】:
非常感谢比尔,感谢您今晚的帮助。只是想知道以下代码行是什么意思? :- 断言 selected.shape == (202, 6) + 断言飞机.index.duplicated().sum() == 0 ? 我需要输入什么,以便显示所有的 DHS、DS、DH?是否可以使用原始字体而不是布尔类型文本将显示的数据更改为最新的? 你可以忽略这些。只需检查以确保行数和列数正确,并证明在 groupby 之后没有重复。你不需要它们。 即显示,就像您在 Jupyter Notebook 中运行原始 Python 代码时一样,仅显示当前更改? 我认为您指的是print(aircraft.head())
声明。 aircraft
是 pd.Series
不是 DataFrame
。这就是为什么它会这样显示。要在 Jupyter 笔记本中查看“漂亮”版本,请使用 pd.DataFrame(aircraft)
以上是关于使用 Pandas 在 Jupyter Notebook 中过滤 Excel 文档数据的主要内容,如果未能解决你的问题,请参考以下文章
Jupyter Notebook又一利器nbterm,在终端玩Python!
从 jupyter-notebook 下载 HTML 文件到本地
Pyechart在Jupyter Lab下无法正确显示图形的问题