【问题标题】:Dropping NaN rows, certain columns in specific excel files using glob/merge使用 glob/merge 删除 NaN 行、特定 excel 文件中的某些列
【发布时间】:2016-08-25 00:08:24
【问题描述】:

我想在加载到 excel 文件中的 for 循环中删除最终文件中的 NaN 行,并删除所有公司、电子邮件、创建的重复列,但最终加载到 excel 文件中。

这是我的 for 循环(以及随后合并到单个 DF),目前:

for f in glob.glob("./gowall-users-export-*.xlsx"):
    df = pd.read_excel(f)
    all_users_sheets_hosts.append(df)
    j = re.search('(\d+)', f)
    df.columns = df.columns.str.replace('.*Hosted Meetings.*', 'Hosted Meetings' + ' ' + j.group(1))

all_users_sheets_hosts = reduce(lambda left,right: pd.merge(left,right,on=['First Name', 'Last Name'], how='outer'), all_users_sheets_hosts)

这是生成的 DF 的前几行:

Company_x   First Name  Last Name   Emails_x    Created_x   Hosted Meetings 03112016    Facilitated Meetings_x  Attended Meetings_x Company_y   Emails_y    ... Created_x   Hosted Meetings 04122016    Facilitated Meetings_x  Attended Meetings_x Company_y   Emails_y    Created_y   Hosted Meetings 04212016    Facilitated Meetings_y  Attended Meetings_y
0   TS  X Y X@Y.com 03/10/2016  0.0 0.0 0.0 TS  X@Y.com ... 03/10/2016  0.0 0.0 2.0 NaN NaN NaN NaN NaN NaN
1   TS  X Y X@Y.com 03/10/2016  0.0 0.0 0.0 TS  X@Y.com ... 01/25/2016  0.0 0.0 0.0 NaN NaN NaN NaN NaN NaN
2   TS  X Y X@Y.com 03/10/2016  0.0 0.0 0.0 TS  X@Y.com ... 04/06/2015  9.0 10.0    17.0    NaN NaN NaN NaN NaN NaN

【问题讨论】:

  • 什么是 NaN 行? any 值是 NaN 的行吗?或 all 值为 NaN 的行?还是...?
  • 在这种情况下,具有任何 NaN 值的行将具有所有 NaN 值,因此没有区别。不过,我应该提到这一点。

标签: python pandas glob


【解决方案1】:

为防止出现多个 CompanyEmailsCreatedFacilitated MeetingsAttended Meetings 列,请将它们从 right 数据帧中删除。要删除包含所有 NaN 值的行,请使用 result.dropna(how='all', axis=0)

import pandas as pd
import functools

for f in glob.glob("./gowall-users-export-*.xlsx"):
    df = pd.read_excel(f)
    all_users_sheets_hosts.append(df)
    j = re.search('(\d+)', f)
    df.columns = df.columns.str.replace('.*Hosted Meetings.*', 
                                        'Hosted Meetings' + ' ' + j.group(1))

# Drop rows of all NaNs from the final DataFrame in `all_users_sheets_hosts`
all_users_sheets_hosts[-1] = all_users_sheets_hosts[-1].dropna(how='all', axis=0)

def mergefunc(left, right):
    cols = ['Company', 'Emails', 'Created', 'Facilitated Meetings', 'Attended Meetings']
    right = right.drop(cols, axis=1)
    result = pd.merge(left, right, on=['First Name', 'Last Name'], how='outer')
    return result

all_users_sheets_hosts = functools.reduce(mergefunc, all_users_sheets_hosts)

自从Company 等。人。列将仅存在于left DataFrame 中,这些列不会扩散。但是请注意,如果 leftright DataFrame 在这些列中具有不同的值,则只会保留 all_users_sheets_hosts 中第一个 DataFrame 中的值。


替代方案,如果 leftright DataFrames 对于 Company 等具有相同的值。人。列,那么另一种选择是也对这些列进行简单合并:

def mergefunc(left, right):
    cols = ['First Name', 'Last Name', 'Company', 'Emails', 'Created', 
            'Facilitated Meetings', 'Attended Meetings']
    result = pd.merge(left, right, on=cols, how='outer')
    return result
all_users_sheets_hosts = functools.reduce(mergefunc, all_users_sheets_hosts)

【讨论】:

  • 非常感谢。我已经成功地使用了您的第一个提案,但是,删除行并不是我想要的。使用您给我的代码,它会尝试删除整个合并数据框中所有(或任何)Na 的行。我想仅在数据框的最后一个合并文件中考虑 Na 行
  • 对不起,我应该更仔细地阅读你的问题。 all_users_sheets_hosts[-1] = all_users_sheets_hosts[-1].dropna(how='all', axis=0) 将仅从 all_users_sheets_hosts 中的 last DataFrame 中删除空 (NaN) 行。
  • 我无法让它工作,我已经玩了一下。 all_users_sheets_hosts[-1] 不是 all_users_sheets_hosts 的最后一列吗?即便如此,它也不会删除最后一列中的 na 行...
  • 紧跟在for f in glob.glob 循环之后,all_users_sheets_hosts 是一个列表。所以all_users_sheets_hosts[-1] 指的是列表中的最后一项。由于 DataFrame 已附加到 for-loop 中的此列表中,因此 all_users_sheets_hosts[-1] 应该是一个 DataFrame。
  • 如果您仍然遇到问题,请尝试准备一个小的可运行示例来演示该问题。给定一个 DataFrame,打印 df.head().reset_index().to_dict('list')df.info() 对我们非常有帮助,这样我们就可以重建您正在处理的情况。如果数据是私有的,只需修改数量值,同时保持质量不变。
猜你喜欢
  • 1970-01-01
  • 2021-09-12
  • 1970-01-01
  • 1970-01-01
  • 2016-05-12
  • 1970-01-01
  • 1970-01-01
  • 2019-12-17
  • 1970-01-01
相关资源
最近更新 更多