def shuffleRows(df, i_bins, c_bins, tracks_map,  groups,
                difference, s_max=100, i=1):

    counts = np.zeros((len(i_bins) + 1, len(c_bins) + 1))
    # JJ
    E.info("Initial count table:")
    E.info(counts)

    indices = {(key1, key2): []
               for key1 in np.digitize(i_bins, i_bins)
               for key2 in np.digitize(c_bins, c_bins)}
    # JJ
    # E.info(indices)

    # find min value in the counts ndarray
    min_occup = min(counts.flatten())

    for iteration in range(0,  i):
        E.info("performing shuffling iteration number %i.." % (iteration + 1))
        # if min value is less than the specified maximum occupancy
        if min_occup < s_max:
            # permute the df index axes to get a random row order
            group1_rand = np.random.permutation(df.index)
            group2_rand = np.random.permutation(df.index)

            # subset the dataframe rows in the first random row order
            # subset the dataframe columns_ids in first group
            # return a list of the means across columns in the random order.
            group1_mean = df.ix[group1_rand,
                                tracks_map[groups[0]]].apply(
                                    np.mean, axis=1).tolist()
            # JJ
            # E.info( group1_mean )

            # same for second random order and column Ids in second group.
            group2_mean = df.ix[group2_rand,
                                tracks_map[groups[1]]].apply(
                                    np.mean, axis=1).tolist()

            # JJ
            # E.info( group2_mean )

            # retrieve the index for the bin in which each of the index
            # values falls.
            change_idx, initial_idx = means2idxarrays(
                group1_mean, group2_mean, i_bins, c_bins, difference)

            # JJ
            # E.info( change_idx )
            # E.info( initial_idx )
            # E.info( initial_idx.__class__ )
            E.info("Max %s" % str(initial_idx.max()))

            # for each of the initial and change values co-ordinates...
            for idx, coord in enumerate(zip(initial_idx, change_idx)):
                # if that combination is desired...
                if coord in indices.keys():
                    if counts[coord] < s_max:
                        counts[coord] += 1
                        # ...append tuple of the expression val for each group
                        indices[coord].append((group1_rand[idx],
                                               group2_rand[idx]))
            min_occup = min(counts.flatten())

    # JJ
    E.info("Final count table:")
    E.info(counts)
    # E.info( indices )

    return indices, counts
dataset/ETHPy150Open CGATOxford/cgat/scripts/data2spike.py/shuffleRows/original