TypeError:Pandas wide_to_long函数需要字符串或缓冲区

ecbunoof  于 2023-04-18  发布在  其他
关注(0)|答案(2)|浏览(103)

我正在尝试使用wide_to_long来重新组织 Dataframe 。
我当前的df看起来像这样,只是有更多的列,最终会像math_b,阅读_c等:

Course Code   StudentID   score-reading_a   letter-reading_a   score-math_a   letter-math_a
ABC123        123456      98                A                  96             A
ABC123        987654      77                C                  88             B
DEF456        102938      88                B                  99             A

我用df['index'] = df.index在末尾添加了一个索引列
我的目标是让df看起来更像这样:

Course Code   Student ID   subject   score   letter
ABC123        123456       reading_a 98      A
ABC123        123456       math_a    96      A
ABC123        987654       reading_a 77      C
ABC123        987654       math_a    88      B
DEF456        102938       reading_a 88      B
DEF456        102938       math_a    99      A

以下是我的声明:
df_out = pd.wide_to_long(df, stubnames=['score', 'letter'], i='index', j='subject', sep='-')
我得到这个错误:

df_out = pd.wide_to_long(df, stubnames=['score', 'letter'], i='index', j='subject', sep='-')        
  File "C:\Users\...\pandas\core\reshape\melt.py", line 446, in wide_to_long
    value_vars = [get_var_names(df, stub, sep, suffix) for stub in stubnames]
  File "C:\Users\...\pandas\core\reshape\melt.py", line 417, in get_var_names
    return [col for col in df.columns if pattern.match(col)]
TypeError: expected string or buffer

我不是很确定这个语句有什么问题。我之前确实使用了这样的列表重命名了列,因为原始的列名非常混乱:

headers = ['Course Code', 'Student ID', 'score-reading_a', 'letter-reading_a',
           'score-math_a', 'letter-math_b']

df.columns = [headers]

这样重新分配列会导致它无法识别列名吗?或者我完全错了,做了一些完全错误的事情?我试图将列名转换为字符串,但抛出了关于MultiIndex的错误,而且我的MultiIndex只有1级。我使用了这样的语句来尝试以不同的方式转换它,但它只是弄乱了头部,并在wide_to_long函数运行后给我留下了一个空的 Dataframe :
df.columns = ['_'.join(col) for col in df.columns.values]
除此之外,我唯一没有写下来的代码是read_csv语句。
我确实通过循环和concat得到了我想要的数据,但我希望使用更精简的东西。

brc7rcf0

brc7rcf01#

我用stack来做:

out = (df.set_index(["Course Code", "StudentID"])
           .pipe(lambda df_: df_.set_axis(df_.columns
                        .str.split("-", expand=True), axis=1))
           .stack().reset_index().rename({"level_2": "subject"}, axis=1)
      )​

输出:

print(out)

  Course Code  StudentID    subject letter  score
0      ABC123     123456     math_a      A     96
1      ABC123     123456  reading_a      A     98
2      ABC123     987654     math_a      B     88
3      ABC123     987654  reading_a      C     77
4      DEF456     102938     math_a      A     99
5      DEF456     102938  reading_a      B     88
xghobddn

xghobddn2#

我使用df.rename函数解决了TypeError,而不是使用列表。这是我在这里的主要问题,我将单独解决其他问题。
感谢您的所有输入-我很感激。

相关问题