我正在使用站点密钥的日志数据,然后是事件和时间戳的密钥/值对。预处理将其作为不确定列数(可以为1-N)的pandas数据帧提供,其中列是键,值是时间戳。我知道这是一个不太理想的结构,但我无法更改。什么是在数据帧上进行操作的有效方法,这样对于每个键,我都能够对非空列进行计数并识别非空值?

这是假设的raw data

KeyCol  ValCol1 ValCol2 ValCol3
A   ValCol1 ValCol2 nan
B   nan nan nan
C   ValCol1 nan ValCol3
D   nan ValCol2 nan
C   nan nan ValCol3


这是desired output

KeyCol  Len Vals
A   2   [ValCol1, ValCol2]
B   0   []
C   2   [ValCol1, ValCol3]
D   1   [ValCol2]


到目前为止,这是我所做的...但是效率似乎很低。我将如何优化它?

import pandas as pd

def iterate_rows_for_nonnulls(df, grouper):
    assert isinstance(df, pd.DataFrame)
    assert isinstance(grouper, (list, tuple))

    aggdic = {}
    for row, data in df.iterrows():
        key = tuple(data[grouper])
        nonnulls = data[~data.index.isin(grouper)]
        nonnulls = nonnulls[nonnulls.notnull()]
        data[data.notnull()]
        if key not in aggdic:
            aggdic[key] = {}
            aggdic[key]['vals'] = nonnulls
        else:
            aggdic[key]['vals'] = aggdic[key]['vals'].append(nonnulls)

    for key, val in aggdic.iteritems():
        aggdic[key]['vals'] = aggdic[key]['vals'].unique()
        aggdic[key]['len'] = len(aggdic[key]['vals'])
    # Testing using [key for key in aggdic.iteritems() if aggdic[key[0]]['len']>0 ]
    return aggdic

def construct_df_from_nonnulls(aggdic):
    assert isinstance(aggdic, dict)
    return pd.DataFrame(dict(aggdic)).T

sourcedf = pd.read_table('https://gist.githubusercontent.com/roablep/a11da82de18b14bd2c3c/raw/257f2fa7634002db267e2ef599d6e0cd330c1c72/Sourcedata', sep = "\t")
aggdic = iterate_rows_for_nonnulls(sourcedf, ['KeyCol'])
resultsdf = construct_df_from_nonnulls(aggdic)

最佳答案

假设我正确地理解了您-列名与这些列中所有元素的值相同是很奇怪的-我认为您可以在groupby之后简单地将melt扔给它:

>>> d2 = pd.melt(df,id_vars="KeyCol")
>>> grouped = d2.groupby("KeyCol", as_index=False)["value"]
>>> dout = grouped.agg({"Len": "nunique",
                        "Vals": lambda x: x.dropna().unique().tolist()})
>>> dout
  KeyCol                Vals  Len
0      A  [ValCol1, ValCol2]    2
1      B                  []    0
2      C  [ValCol1, ValCol3]    2
3      D           [ValCol2]    1


强烈建议阅读split-apply-combine模式下的doc部分。

就是说,请注意,将非标量对象(例如Series或DataFrames中的列表)作为元素是令人头痛的秘诀-确实不支持它们。有时它可以作为中间步骤的临时措施而有用,但是制作该系列后,您实际上不能做太多事情。

关于python - 有效地将pandas数据框列名转换为行值,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/27996043/

10-12 17:00
查看更多