根据多行将Dataframe拆分为多个部分

时间:2017-09-28 23:16:28

标签: python pandas numpy dataframe k-means

所以我想知道是否可以对具有多行的数据帧进行排序。例如,假设有一个包含5行的数据帧,我想随机选择几行,在这种情况下假设为2,我将其指定为centroid1和centroid2,然后根据这些行对数据帧进行排序。在这种情况下,小于centroid1的行位于其上方,大于centroid1但小于centroid2的行位于它们之间,而大于centroid2的行位于centroid2之下。

def compareRows(arr1, arr2):
    a1 = sum(arr1)
    a2 = sum(arr2)
    return a1 > a2 

此功能是我比较行的方式。

    data = np.array(pd.read_csv('https://raw.githubusercontent.com/gsprint23/cpts215/master/progassignments/files/cancer.csv',  header=None))
    data = data.T
    #print(data)
    df = pd.DataFrame(data[1:], columns=data[0], dtype=float).T

    sampled = df.sample(1)
    d = df.drop(sampled.index)
    gt = d.apply(compareRows, 1, arr2=sampled.squeeze())
    df = pd.concat([d[~gt], sampled, d[gt]])

我理解如何用一行做到这一点。上面的代码读入数据集,然后将其放入数据框中。之后,它从帧中取一个样本,将其删除,然后应用compareRows函数来比较其他行是大于还是小于它并将它们附加到正确的位置。我的问题是是否有可能推广这个过程,以便可以用1,2,3 ...... n行完成。因此,如果我选择3个中心,它将类似于我上面的2个中心的示例,但是会有另一个中心对数据进行分区。

任何建议表示赞赏。如果您需要有关该问题的任何进一步信息或解释,请与我们联系。

感谢您阅读

1 个答案:

答案 0 :(得分:1)

只要样本已经按其总和的递增顺序

,我们就可以迭代地应用比较行
def compareRows(arr1, arr2):
    a1 = sum(arr1)
    a2 = sum(arr2)
    return a1 > a2 

def sort_centroids(samples): #just sorts the samples in increasing order of their sum
    order = [float(i.sum(axis=1)) for i in samples]
    std=sorted(zip(samples,order),key=lambda x: x[1],reverse=True)
    return [i[0] for i in std]

import numpy as np
import pandas as pd

data = np.array(pd.read_csv('https://raw.githubusercontent.com/gsprint23/cpts215/master/progassignments/files/cancer.csv',  header=None))
data = data.T
df = pd.DataFrame(data[1:], columns=data[0], dtype=float).T

num_centroids = 10

samples = [df.sample(1) for i in range(num_centroids)]
samples = sort_centroids(samples)

for i in range(num_centroids): #loop over centroids one by one
    d = df.drop(samples[i].index)
    gt = d.apply(compareRows, 1, arr2=samples[i].squeeze())
    df = pd.concat([d[~gt], samples[i], d[gt]])
理智检查:

o=[float(i.sum(axis=1)) for i in samples]
o.reverse()
print(o)
print()
print(df.sum(axis=1))