【问题标题】:Processing one column text by index to several new columns based on specific word in text根据文本中的特定单词通过索引处理一列文本到几个新列
【发布时间】:2017-10-20 01:57:48
【问题描述】:

我在使用 pandas 代码时遇到问题,在尝试寻找答案数小时后,我终于放弃并来这里寻求帮助!

我的数据框是从较大的 excel 文件创建的,它包含同时定义为索引的特定观察值。现在我有一个专栏,其中这些观察提供了文本答案,并且这些观察中的大多数都提供了几个响应。这是我的输出示例。

Org        Data1
 x          aaa
 x          aaa
 x          bbb
 y          aaa
 z          ccc
 z          ddd
 z          ddd

我想要实现的是:

 Org    One    Two    Three   Four
  x      1      1      0       0
  y      1      0      0       0
  z      0      0      1       1

 Data1 column is deleted and new columns correspond text answers like this: 
 "One" = aaa, "Two" = bbb, "Three" = ccc, and "Four" = ddd.

这个想法是通过索引“Org”将所有内容组合在一起,并根据“Data1”列的答案创建新列。因此,在示例中,由于“Org”x 在“Data1”中响应 aaa 两次和 bbb 一次,代码将创建一个新列“One”和“Two”,并使用 true 或 false 函数将 1 或 0 放置到这个新的柱子。这个想法也是忽略多次给出的响应,但我猜对于 true 或 false 函数,这不是问题,也不需要删除重复项(?)。请注意,答案没有任何特定的顺序,我总共有大约 10000 行,我使用 loc 来选择我感兴趣的特定“Org”:s。

这是我迄今为止尝试过的:

df = pd.read_excel("location\test.xlsx", sheetname="Sheet1", 
index_col="Org").loc[["x", "y", "z"], ["Data1"]]

df["One"] = np.where(df["Data1"].str.contains["aaa"], "1", "0")

通过同时执行 df["Two"]、df["Three"] 等,最后删除 Data1 列,并通过使用 groupby 和 sum 进一步处理结果,我能够得到最终结果。但是,然后我有带有“2”或“3”的列,而不是我正在寻找的“1”。显然,这不是一项需要进一步处理的艰巨任务,但我一直在尝试提出比 groupby 和 sum 更好的解决方案,因为这将有助于将来处理这个 excel 文件。

我尝试过的如下:

1
df = pd.read_excel("location\test.xlsx", sheetname="Sheet1", 
index_col="Org").loc[["x", "y", "z"], ["Data1"]].groupby("Org").agg(lambda
x: set (x))

2
df = pd.read_excel("location\test.xlsx", sheetname="Sheet1", 
index_col="Org").loc[["x", "y", "z"], ["Data1"]].groupby(["Org"])
["Data1"].agg(lambda x: ";;".join(set(x.astype(str)))).str.split(";;")

第一个解决方案工作正常,因为它将相同的索引“Org”答案分组到前几行中的一行。但是,当应用 np.where 和 str.contains 时,我收到了新列“One”,其中每个观察“Org”都有“1”,这是错误的。第二种解决方案无法正常运行,因为它丢失了在处理每个可能的“aaa”“bbb”“ccc”“ddd”答案之前所需的原始列名,并且我无法使用 np 查找“aaa” .where 和 str.contains。

有没有人能帮我解决这个“棘手”的问题,因为我还在学习熊猫。提前谢谢!

【问题讨论】:

    标签: python excel pandas


    【解决方案1】:

    一种方法是使用 Pandas 的 pivot_table

    df['num_val']=1
    df=df.pivot_table(values='num_val', columns='Data1', index='Org', fill_value=0)
    df.columns=['One', 'Two', 'Three', 'Four']
    

    【讨论】:

    • 可选地将 reset_index 添加到最后一行以获得您想要的确切形式(org 作为列而不是索引)
    • 非常感谢!这几乎完美无缺。不知何故,此代码缺少未响应任何内容的索引“Org”观察结果,因此我缺少行。我尝试在 fill_value=0 之后添加 dropna=False 但它不起作用。知道如何让这些没有回应的观察也参与进来吗?
    • @hexi:看我下面的回答
    • 得到这个工作然后使用 fillna("NAN", inplace=True) 然后应用该方法。最后我只删除了 NAN 列。
    【解决方案2】:

    您可以通过旋转表格然后应用条件来获得:

    df1=pd.pivot_table(df,index='Org', values=['Org'], columns=['Data1'], aggfunc=len, fill_value=0).fillna(0).reset_index()
    df1.index.name=None 
    df1.columns = ["Org","One","Two","Three","Four"]
    df1.set_index('Org', inplace=True)
    df1.applymap(lambda x: 1 if x>=1 else 0)
    

    【讨论】:

    • 也感谢您的帮助。第一行中的“Org”似乎存在关键错误,但我还没有发现原因,因为一切似乎都很好,至少从初学者的角度来看。我正在尝试查找我输入的代码中的错误。
    • 我将您的第一个输出与 Org 和 Data1 一起用作 csv
    • 是否有区别,因为我构建数据框的原始数据来自xlsx?
    • 您已经使用 Org.所以在我的代码 sn-p 中,删除 set_index 你应该很好。检查列。可以肯定的是,在您从 excel 中读取数据后分享您的数据框。
    • 我仍在努力,问题在第一行,我不断收到 KeyError "Org"。这可能是因为在阅读 excel 时我已经将 index_col 设置为“Org”吗?
    猜你喜欢
    • 2022-07-07
    • 1970-01-01
    • 2017-05-23
    • 1970-01-01
    • 1970-01-01
    • 2011-07-17
    • 2021-11-27
    • 2019-10-19
    • 1970-01-01
    相关资源
    最近更新 更多