现在有很多类似的问题,但是大多数回答了如何删除重复的列。但是,我想知道如何制作一个元组列表,其中每个元组都包含重复列的列名。我假设每一列都有一个唯一的名称。为了进一步说明我的问题:
df = pd.DataFrame({'A': [1, 2, 3, 4, 5],'B': [2, 4, 2, 1, 9],
'C': [1, 2, 3, 4, 5],'D': [2, 4, 2, 1, 9],
'E': [3, 4, 2, 1, 2],'F': [1, 1, 1, 1, 1]},
index = ['a1', 'a2', 'a3', 'a4', 'a5'])
然后我想要输出:
[('A', 'C'), ('B', 'D')]
如果今天您感觉很好,则将相同的问题扩展到行。如何获取元组列表,其中每个元组都包含重复的行。
这是NumPy的一种方法-
def group_duplicate_cols(df):
a = df.values
sidx = np.lexsort(a)
b = a[:,sidx]
m = np.concatenate(([False], (b[:,1:] == b[:,:-1]).all(0), [False] ))
idx = np.flatnonzero(m[1:] != m[:-1])
C = df.columns[sidx].tolist()
return [C[i:j] for i,j in zip(idx[::2],idx[1::2]+1)]
样品运行-
In [100]: df
Out[100]:
A B C D E F
a1 1 2 1 2 3 1
a2 2 4 2 4 4 1
a3 3 2 3 2 2 1
a4 4 1 4 1 1 1
a5 5 9 5 9 2 1
In [101]: group_duplicate_cols(df)
Out[101]: [['A', 'C'], ['B', 'D']]
# Let's add one more duplicate into group containing 'A'
In [102]: df.F = df.A
In [103]: group_duplicate_cols(df)
Out[103]: [['A', 'C', 'F'], ['B', 'D']]
进行转换即可,但是对于rows(index),我们只需要沿另一条轴切换操作,就像这样-
def group_duplicate_rows(df):
a = df.values
sidx = np.lexsort(a.T)
b = a[sidx]
m = np.concatenate(([False], (b[1:] == b[:-1]).all(1), [False] ))
idx = np.flatnonzero(m[1:] != m[:-1])
C = df.index[sidx].tolist()
return [C[i:j] for i,j in zip(idx[::2],idx[1::2]+1)]
样品运行-
In [260]: df2
Out[260]:
a1 a2 a3 a4 a5
A 3 5 3 4 5
B 1 1 1 1 1
C 3 5 3 4 5
D 2 9 2 1 9
E 2 2 2 1 2
F 1 1 1 1 1
In [261]: group_duplicate_rows(df2)
Out[261]: [['B', 'F'], ['A', 'C']]
方法-
# @John Galt's soln-1
from itertools import combinations
def combinations_app(df):
return[x for x in combinations(df.columns, 2) if (df[x[0]] == df[x[-1]]).all()]
# @Abdou's soln
def pandas_groupby_app(df):
return [tuple(d.index) for _,d in df.T.groupby(list(df.T.columns)) if len(d) > 1]
# @COLDSPEED's soln
def triu_app(df):
c = df.columns.tolist()
i, j = np.triu_indices(len(c), 1)
x = [(c[_i], c[_j]) for _i, _j in zip(i, j) if (df[c[_i]] == df[c[_j]]).all()]
return x
# @cmaher's soln
def lambda_set_app(df):
return list(filter(lambda x: len(x) > 1, list(set([tuple([x for x in df.columns if all(df[x] == df[y])]) for y in df.columns]))))
注意:@John Galt's soln-2
未包括在内,因为输入的大小(8000,500)
会与针对该输入的提议不符broadcasting
。
时间-
In [179]: # Setup inputs with sizes as mentioned in the question
...: df = pd.DataFrame(np.random.randint(0,10,(8000,500)))
...: df.columns = ['C'+str(i) for i in range(df.shape[1])]
...: idx0 = np.random.choice(df.shape[1], df.shape[1]//2,replace=0)
...: idx1 = np.random.choice(df.shape[1], df.shape[1]//2,replace=0)
...: df.iloc[:,idx0] = df.iloc[:,idx1].values
...:
# @John Galt's soln-1
In [180]: %timeit combinations_app(df)
1 loops, best of 3: 24.6 s per loop
# @Abdou's soln
In [181]: %timeit pandas_groupby_app(df)
1 loops, best of 3: 3.81 s per loop
# @COLDSPEED's soln
In [182]: %timeit triu_app(df)
1 loops, best of 3: 25.5 s per loop
# @cmaher's soln
In [183]: %timeit lambda_set_app(df)
1 loops, best of 3: 27.1 s per loop
# Proposed in this post
In [184]: %timeit group_duplicate_cols(df)
10 loops, best of 3: 188 ms per loop
借助NumPy的视图功能实现超级助推
借助NumPy的视图功能,我们可以将每组元素视为一个dtype,这样可以进一步提高性能,如下所示-
def view1D(a): # a is array
a = np.ascontiguousarray(a)
void_dt = np.dtype((np.void, a.dtype.itemsize * a.shape[1]))
return a.view(void_dt).ravel()
def group_duplicate_cols_v2(df):
a = df.values
sidx = view1D(a.T).argsort()
b = a[:,sidx]
m = np.concatenate(([False], (b[:,1:] == b[:,:-1]).all(0), [False] ))
idx = np.flatnonzero(m[1:] != m[:-1])
C = df.columns[sidx].tolist()
return [C[i:j] for i,j in zip(idx[::2],idx[1::2]+1)]
时间-
In [322]: %timeit group_duplicate_cols(df)
10 loops, best of 3: 185 ms per loop
In [323]: %timeit group_duplicate_cols_v2(df)
10 loops, best of 3: 69.3 ms per loop
只是疯狂的加速!
问题内容: 这是我的数据框,应重复5次: 我想要这样的结果: 但是必须有一种比保持追加更聪明的方法。实际上,Im正在处理的数据帧应重复50次。 我还没有发现任何实用的东西,包括类似-—的东西,但它在数据框架上不起作用。 有人可以帮忙吗? 问题答案: 您可以使用以下功能: 如果只想重复值而不是索引,则可以执行以下操作:
问题内容: 我想在中设置多列的(我有一个文件,我不得不手动将其解析为列表列表,因为该文件不适合) 我懂了 我可以设置它们的唯一方法是循环遍历每个列变量并使用重铸。 有没有更好的办法? 问题答案: 从0.17开始,您必须使用显式转换: (如下所述,在0.17中已不再使用“魔术”了) 您可以将它们应用于要转换的每一列: 并确认dtype已更新。 适用于大熊猫0.12-0.16的旧/建议答案:您可以用来
问题内容: 给定一个记录某些书籍使用情况的数据框,如下所示: 我需要获取所有书籍的数量,保留其他列并获取以下内容: 如何才能做到这一点? 谢谢! 问题答案: 您需要以下内容: 在您的情况下,“名称”,“类型”和“ ID”列的值匹配,因此我们可以对它们进行调用,然后单击。 另一种方法是使用添加“ Count”列,然后调用:
问题内容: 我有一个具有此类数据的数据框(列过多): 列看起来像这样: 我想像这样将列中的所有值转换为整数: 我通过以下方法解决了这一问题: 现在,我的数据框中有两列-旧列和新列,需要删除旧列。 那是不好的做法。它是可行的,但是在我的数据框中有很多列,我不想手动进行。 pythonic如何巧妙地实现呢? 问题答案: 首先,要将“分类”列转换为其数字代码,可以使用以下命令更轻松地做到这一点。 此外,
问题内容: 这应该很容易,但是以某种方式我找不到有效的解决方案。 我有一个熊猫数据框,看起来像这样: 我想按col1和col2分组并获得col3和col4。 由于无法汇总数据,因此可以删除。 这是输出的样子。我很感兴趣,同时具有和中产生的数据帧。是否和是否属于索引并不重要。 这是我尝试过的: 但是,这只会返回的汇总结果。 我在这里迷路了。我发现的每个示例仅汇总一列,显然不会发生此问题。 问题答案:
问题内容: 如果数据如下所示: 我想复制IsHoliday等于TRUE的行,我可以这样做: 但是是否有更好的方法来执行此操作,因为我需要将假日行重复5次,如果使用上述方法,则必须追加5次。 问题答案: 您可以放入列表中,然后执行以下操作: