নিম্পিতে দ্রুত প্রতিসাম্যযুক্ত জোড়গুলি সন্ধান করুন


15
from itertools import product
import pandas as pd

df = pd.DataFrame.from_records(product(range(10), range(10)))
df = df.sample(90)
df.columns = "c1 c2".split()
df = df.sort_values(df.columns.tolist()).reset_index(drop=True)
#     c1  c2
# 0    0   0
# 1    0   1
# 2    0   2
# 3    0   3
# 4    0   4
# ..  ..  ..
# 85   9   4
# 86   9   5
# 87   9   7
# 88   9   8
# 89   9   9
# 
# [90 rows x 2 columns]

আমি কীভাবে দ্রুত এই ডেটা ফ্রেমের সমস্ত প্রতিসাম্পত্তিযুক্ত জোড়গুলির শেষ সদৃশ খুঁজে পেতে, সনাক্ত করতে এবং সরিয়ে ফেলি?

প্রতিসম জুটির উদাহরণ হ'ল '(0, 1)' এর সমান '(1, 0)'। পরেরটি সরিয়ে ফেলা উচিত।

অ্যালগরিদম অবশ্যই দ্রুত হওয়া উচিত, তাই এটি নম্পটি ব্যবহার করার পরামর্শ দেওয়া হয়। পাইথন অবজেক্টে রূপান্তর করার অনুমতি নেই।


1
আপনি যা বোঝেন তার একটি উদাহরণ দিতে পারেন symmetric pairs?
ইয়াতু

(0, 1) == (1,0) সত্য
দ্য আনফুন বিড়াল

1
(0, 1) == (0, 1) এছাড়াও সত্য?
ওউন্ডারম্যান 45

@JerryM। হ্যাঁ, তবে এর সাথে অপসারণ করা তুচ্ছdf.drop_duplicates()
দ্য আনফুন বিড়াল

2
@ মোলিবেডেনাম 42 আমি উদাহরণ তৈরির জন্য ইটারটুলস পণ্যটি ব্যবহার করি, ডেটা তারা নিজেরাই ইটারল্টস পণ্য দিয়ে তৈরি করে না।
আনফুন বিড়াল

উত্তর:


13

আপনি মানগুলি বাছাই করতে পারেন, তারপরে groupby:

a= np.sort(df.to_numpy(), axis=1)
df.groupby([a[:,0], a[:,1]], as_index=False, sort=False).first()

অপশন 2 : আপনি জোড়া অনেক আছে তাহলে c1, c2, groupbyধীর হতে পারে। সেক্ষেত্রে আমরা নতুন মান নির্ধারণ করতে পারি এবং এর মাধ্যমে ফিল্টার করতে পারি drop_duplicates:

a= np.sort(df.to_numpy(), axis=1) 

(df.assign(one=a[:,0], two=a[:,1])   # one and two can be changed
   .drop_duplicates(['one','two'])   # taken from above
   .reindex(df.columns, axis=1)
)

7

ওয়ান ওয়ে ব্যবহার করছে np.uniqueসঙ্গে return_index=Trueএবং সূচক dataframe কাছে ফলাফলের ব্যবহার করুন:

a = np.sort(df.values)
_, ix = np.unique(a, return_index=True, axis=0)

print(df.iloc[ix, :])

    c1  c2
0    0   0
1    0   1
20   2   0
3    0   3
40   4   0
50   5   0
6    0   6
70   7   0
8    0   8
9    0   9
11   1   1
21   2   1
13   1   3
41   4   1
51   5   1
16   1   6
71   7   1
...

1
হ্যাঁ অন্যথায় অনন্য প্রতিদ্বন্দ্বী জোড়গুলি সনাক্ত করতে ব্যর্থ হয়েছে
@

ঠিক আছে, আমি দেখতে পাচ্ছি আপনি
জোড়গুলি

হ্যাঁ তবে আমি বোঝাতে চাইছি আপনি [1, 0] কে ঠিক [0, 1] এ রূপান্তর করেছেন?
দানি মেসেজো

6

frozenset

mask = pd.Series(map(frozenset, zip(df.c1, df.c2))).duplicated()

df[~mask]

1
আপনি কি এখানে প্রতিটি কলামের উপরে ধীরে ধীরে পুনরাবৃত্তি করছেন? এখনও, upvote।
আনফুন বিড়াল

হ্যাঁ, আমি পুনরাবৃত্তি করছি। না, এটি আপনার মনে হয় তেমন ধীর হয় না।
পাইরেসওয়ার্ড

5

আমি করব

df[~pd.DataFrame(np.sort(df.values,1)).duplicated().values]

পান্ডা এবং অদ্ভুত ত্রি থেকে

s=pd.crosstab(df.c1,df.c2)
s=s.mask(np.triu(np.ones(s.shape)).astype(np.bool) & s==0).stack().reset_index()

5

পূর্ণসংখ্যার জন্য এখানে একটি নম্পপি ভিত্তিক -

def remove_symm_pairs(df):
    a = df.to_numpy(copy=False)
    b = np.sort(a,axis=1)
    idx = np.ravel_multi_index(b.T,(b.max(0)+1))
    sidx = idx.argsort(kind='mergesort')
    p = idx[sidx]
    m = np.r_[True,p[:-1]!=p[1:]]
    a_out = a[np.sort(sidx[m])]
    df_out = pd.DataFrame(a_out)
    return df_out

আপনি যদি সূচী তথ্যটি যেমন রাখতে চান তবে ব্যবহার করুন return df.iloc[np.sort(sidx[m])]

জেনেরিক সংখ্যার জন্য (ints / floats ইত্যাদি), আমরা একটি ব্যবহার করব view-based-

# https://stackoverflow.com/a/44999009/ @Divakar
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()

কেবল পেতে পদক্ষেপ প্রতিস্থাপন idxসঙ্গে idx = view1D(b)মধ্যে remove_symm_pairs


1

যদি এটি দ্রুত হওয়া দরকার , এবং যদি আপনার ভেরিয়েবলগুলি পূর্ণসংখ্যা হয়, তবে নিম্নলিখিত কৌশলটি সাহায্য করতে পারে: আসুন v,wআপনার ভেক্টরের কলাম হতে দিন ; নির্মাণ করা [v+w, np.abs(v-w)] =: [x, y]; তারপরে এই ম্যাট্রিক্সকে ডিক্সিকোগ্রাফিকভাবে বাছাই করুন, সদৃশগুলি সরিয়ে ফেলুন এবং শেষ পর্যন্ত এটিকে ম্যাপ করুন [v, w] = [(x+y), (x-y)]/2

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.