পান্ডাস ডেটা ফ্রেম থেকে কলামের কেবলমাত্র অংশটি আনল্ট করুন


9

আমার কাছে ডেটাফ্রেমের নিম্নলিখিত উদাহরণ রয়েছে:

df = pd.DataFrame(data = {'RecordID' : [1,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5], 'DisplayLabel' : ['Source','Test','Value 1','Value 2','Value3','Source','Test','Value 1','Value 2','Source','Test','Value 1','Value 2','Source','Test','Value 1','Value 2','Source','Test','Value 1','Value 2'],
'Value' : ['Web','Logic','S','I','Complete','Person','Voice','>20','P','Mail','OCR','A','I','Dictation','Understandable','S','I','Web','Logic','R','S']})

যা এই ডেটাফ্রেম তৈরি করে:

+-------+----------+---------------+----------------+
| Index | RecordID | Display Label |     Value      |
+-------+----------+---------------+----------------+
|     0 |        1 | Source        | Web            |
|     1 |        1 | Test          | Logic          |
|     2 |        1 | Value 1       | S              |
|     3 |        1 | Value 2       | I              |
|     4 |        1 | Value 3       | Complete       |
|     5 |        2 | Source        | Person         |
|     6 |        2 | Test          | Voice          |
|     7 |        2 | Value 1       | >20            |
|     8 |        2 | Value 2       | P              |
|     9 |        3 | Source        | Mail           |
|    10 |        3 | Test          | OCR            |
|    11 |        3 | Value 1       | A              |
|    12 |        3 | Value 2       | I              |
|    13 |        4 | Source        | Dictation      |
|    14 |        4 | Test          | Understandable |
|    15 |        4 | Value 1       | S              |
|    16 |        4 | Value 2       | I              |
|    17 |        5 | Source        | Web            |
|    18 |        5 | Test          | Logic          |
|    19 |        5 | Value 1       | R              |
|    20 |        5 | Value 2       | S              |
+-------+----------+---------------+----------------+

আমি উত্সাহিত করার চেষ্টা করছি যদিও উত্সটি সঠিক নয় এবং কলামগুলি নতুন ডেটাফ্রেম কলামগুলিতে পরীক্ষা করা হয়েছে যাতে এটি দেখতে দেখতে:

+-------+----------+-----------+----------------+---------------+----------+
| Index | RecordID |  Source   |      Test      | Result        |  Value   |
+-------+----------+-----------+----------------+---------------+----------+
|     0 |        1 | Web       | Logic          | Value 1       | S        |
|     1 |        1 | Web       | Logic          | Value 2       | I        |
|     2 |        1 | Web       | Logic          | Value 3       | Complete |
|     3 |        2 | Person    | Voice          | Value 1       | >20      |
|     4 |        2 | Person    | Voice          | Value 2       | P        |
|     5 |        3 | Mail      | OCR            | Value 1       | A        |
|     6 |        3 | Mail      | OCR            | Value 2       | I        |
|     7 |        4 | Dictation | Understandable | Value 1       | S        |
|     8 |        4 | Dictation | Understandable | Value 2       | I        |
|     9 |        5 | Web       | Logic          | Value 1       | R        |
|    10 |        5 | Web       | Logic          | Value 2       | S        |
+-------+----------+-----------+----------------+---------------+----------+

এটি আমার বোধগম্য যে পাইভট এবং গলানো পুরো ডিসপ্লে লেবেল কলামটি করবে এবং কেবলমাত্র কিছু মান নয়।

আমি পান্ডাস মেল্ট এবং পান্ডস পিভট পাশাপাশি স্ট্যাকওভারফ্লো সম্পর্কে কিছু উল্লেখ পড়েছি বলে কোনও সাহায্যের প্রশংসা করা হবে এবং এটি করার জন্য আমি কোনও উপায় খুঁজে বের করতে পারি না বলে মনে হয়।

ধন্যবাদ!


আপনি কীভাবে জানবেন যে আপনার আসল ডেটাফ্রেমের ফলাফলটি কোন পরীক্ষার সাথে জড়িত? উদাহরণস্বরূপ 2 উদাহরণস্বরূপ, আপনি কীভাবে জানবেন যে এটি আপনার দ্বিতীয় ডেটাফ্রেমে পরীক্ষার সারির Value 1অধীনে Logicচলেছে?
নাথান ক্লিমেন্ট

হাই নাথান! চূড়ান্ত সারণীতে আমি ভুল করেছিলাম, রেকর্ড আইডি সমস্ত উত্স এবং মানগুলির এক সাথে গোষ্ঠী হিসাবে। দুঃক্ষিত।
জন

উত্তর:


6

যুক্তি প্রয়োগ এবং পাইভোটিং প্রয়োগের মাধ্যমে আমরা আপনার ফলাফল অর্জন করতে পারি, DisplayLabelরয়েছে কিনা তা পরীক্ষা করে আমরা আপনার ডেটা বিভক্ত করি Valueএবং তারপরে আমরা joinসেগুলি আবার একত্রিত করতে পারি:

mask = df['DisplayLabel'].str.contains('Value')
df2 = df[~mask].pivot(index='RecordID', columns='DisplayLabel', values='Value')

dfpiv = (
    df[mask].rename(columns={'DisplayLabel':'Result'})
            .set_index('RecordID')
            .join(df2)
            .reset_index()
)
    RecordID   Result     Value     Source            Test
0          1  Value 1         S        Web           Logic
1          1  Value 2         I        Web           Logic
2          1   Value3  Complete        Web           Logic
3          2  Value 1       >20     Person           Voice
4          2  Value 2         P     Person           Voice
5          3  Value 1         A       Mail             OCR
6          3  Value 2         I       Mail             OCR
7          4  Value 1         S  Dictation  Understandable
8          4  Value 2         I  Dictation  Understandable
9          5  Value 1         R        Web           Logic
10         5  Value 2         S        Web           Logic

আপনি যদি উদাহরণ হিসাবে সঠিক কলামের আদেশ চান তবে ব্যবহার করুন DataFrame.reindex:

dfpiv.reindex(columns=['RecordID', 'Source', 'Test', 'Result', 'Value'])

    RecordID     Source            Test   Result     Value
0          1        Web           Logic  Value 1         S
1          1        Web           Logic  Value 2         I
2          1        Web           Logic   Value3  Complete
3          2     Person           Voice  Value 1       >20
4          2     Person           Voice  Value 2         P
5          3       Mail             OCR  Value 1         A
6          3       Mail             OCR  Value 2         I
7          4  Dictation  Understandable  Value 1         S
8          4  Dictation  Understandable  Value 2         I
9          5        Web           Logic  Value 1         R
10         5        Web           Logic  Value 2         S

বিস্তারিত - ধাপে ধাপ:

# mask all rows where "Value" is in column DisplayLabel
mask = df['DisplayLabel'].str.contains('Value')

0     False
1     False
2      True
3      True
4      True
5     False
6     False
7      True
8      True
9     False
10    False
11     True
12     True
13    False
14    False
15     True
16     True
17    False
18    False
19     True
20     True
Name: DisplayLabel, dtype: bool
# select all rows which do NOT have "Value" in DisplayLabel
df[~mask]

    RecordID DisplayLabel           Value
0          1       Source             Web
1          1         Test           Logic
5          2       Source          Person
6          2         Test           Voice
9          3       Source            Mail
10         3         Test             OCR
13         4       Source       Dictation
14         4         Test  Understandable
17         5       Source             Web
18         5         Test           Logic
# pivot the values in DisplayLabel to columns
df2 = df[~mask].pivot(index='RecordID', columns='DisplayLabel', values='Value')

DisplayLabel     Source            Test
RecordID                               
1                   Web           Logic
2                Person           Voice
3                  Mail             OCR
4             Dictation  Understandable
5                   Web           Logic
df[mask].rename(columns={'DisplayLabel':'Result'}) # rename the column DisplayLabel to Result
            .set_index('RecordID')                 # set RecordId as index so we can join df2 
            .join(df2)                             # join df2 back to our dataframe based RecordId
            .reset_index()                         # reset index so we get RecordId back as column

    RecordID   Result     Value     Source            Test
0          1  Value 1         S        Web           Logic
1          1  Value 2         I        Web           Logic
2          1   Value3  Complete        Web           Logic
3          2  Value 1       >20     Person           Voice
4          2  Value 2         P     Person           Voice
5          3  Value 1         A       Mail             OCR
6          3  Value 2         I       Mail             OCR
7          4  Value 1         S  Dictation  Understandable
8          4  Value 2         I  Dictation  Understandable
9          5  Value 1         R        Web           Logic
10         5  Value 2         S        Web           Logic

আপনার পদক্ষেপগুলি কী করছে তা দয়া করে বিস্তারিত বলতে পারেন? আমি মনে করি আমি অনুসরণ করি তবে স্ট্যাক ওভারফ্লোতে আমার এবং অন্যান্য ব্যক্তির পক্ষে এটি খুব সহায়ক হতে পারে। বিশেষত, যদি আপনার আরও কলাম থাকে তবে আপনি কীভাবে এটি সংশোধন করবেন। সমাধানের জন্য অনেক ধন্যবাদ!
জন

অবশ্যই, সম্পাদনা দেখুন, আমি বিস্তারিত ব্যাখ্যায় একটি বিস্তৃত লিখেছি। আশা করি এটি @ জোন
এরফান

অনেক ধন্যবাদ @ ইরফান! যখন আমি পাইভট স্টেপে পৌঁছে যাই তখন আমি একটি অদ্ভুত ত্রুটির মধ্যে পড়ছি, আমি এটি পেতে থাকি: সূচীতে সদৃশ এন্ট্রি রয়েছে, পুনরায় আকার দিতে পারে না। কোন ধারনা?
জন

6

set_index, unstackতারপরmelt

df.set_index(['RecordID', 'DisplayLabel']).Value.unstack().reset_index() \
  .melt(['RecordID', 'Source', 'Test'], var_name='Result', value_name='Value') \
  .sort_values('RecordID').dropna(subset=['Value'])

    RecordID     Source            Test   Result     Value
0          1        Web           Logic  Value 1         S
5          1        Web           Logic  Value 2         I
10         1        Web           Logic  Value 3  Complete
1          2     Person           Voice  Value 1       >20
6          2     Person           Voice  Value 2         P
2          3       Mail             OCR  Value 1         A
7          3       Mail             OCR  Value 2         I
3          4  Dictation  Understandable  Value 1         S
8          4  Dictation  Understandable  Value 2         I
4          5        Web           Logic  Value 1         R
9          5        Web           Logic  Value 2         S

জন্য কাস্টম ফাংশন groupby

def f(t):
    name, df = t
    d = dict(zip(df['DisplayLabel'], df['Value']))
    source = d.pop('Source')
    test = d.pop('Test')
    result, value = zip(*d.items())

    return pd.DataFrame(
        dict(RecordID=name, Source=source, Test=test, Result=result, Value=value)
    )

pd.concat(map(f, df.groupby('RecordID')))

   RecordID     Source            Test   Result     Value
0         1        Web           Logic  Value 1         S
1         1        Web           Logic  Value 2         I
2         1        Web           Logic  Value 3  Complete
0         2     Person           Voice  Value 1       >20
1         2     Person           Voice  Value 2         P
0         3       Mail             OCR  Value 1         A
1         3       Mail             OCR  Value 2         I
0         4  Dictation  Understandable  Value 1         S
1         4  Dictation  Understandable  Value 2         I
0         5        Web           Logic  Value 1         R
1         5        Web           Logic  Value 2         S

সেটআপ

df = pd.DataFrame(data={
    'RecordID': [1, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5],
    'DisplayLabel': [
        'Source', 'Test', 'Value 1', 'Value 2', 'Value 3',
        'Source', 'Test', 'Value 1', 'Value 2',
        'Source', 'Test', 'Value 1', 'Value 2',
        'Source', 'Test', 'Value 1', 'Value 2',
        'Source', 'Test', 'Value 1', 'Value 2'
    ],
    'Value': [
        'Web', 'Logic', 'S', 'I', 'Complete',
        'Person', 'Voice', '>20', 'P',
        'Mail', 'OCR', 'A', 'I',
        'Dictation', 'Understandable', 'S', 'I',
        'Web', 'Logic', 'R', 'S'
    ]
})

আপনার পদক্ষেপগুলি কী করছে তা দয়া করে বিস্তারিত বলতে পারেন? আমি মনে করি আমি অনুসরণ করি তবে স্ট্যাক ওভারফ্লোতে আমার এবং অন্যান্য ব্যক্তির পক্ষে এটি খুব সহায়ক হতে পারে। বিশেষত, যদি আপনার আরও কলাম থাকে তবে আপনি কীভাবে এটি সংশোধন করবেন। সমাধানের জন্য অনেক ধন্যবাদ!
জন

0

আমি প্রথমে pivotআইং ব্যবহার করে unstackএবং পরে আংশিক রূপান্তর করার ভিন্ন পদ্ধতির চেষ্টা করেছি wide_to_long(দুঃখিত যদি এটি দক্ষ না হয় তবে এটি পছন্দসই আউটপুট পেতে পারে)

# first converting all long to wide
df2 = df.set_index(['RecordID','DisplayLabel']).unstack()
# flattening the unstacked columns
df2.columns = df2.columns.to_series().str.join('_')
df2.columns = df2.columns.str.replace('Value_','',regex=True) #just removing the junk in the column name
df2 = df2.reset_index() #resetting index to access RecordID

df2 = (pd.melt(df2,id_vars=['RecordID',"Source","Test"],var_name='Result', value_name='Value')
.sort_values(['RecordID',"Source","Test"])
.dropna()
.reset_index())
index   RecordID    Source  Test    Result  Value
0   0   1   Web Logic   Value 1 S
1   5   1   Web Logic   Value 2 I
2   10  1   Web Logic   Value 3 Complete
3   1   2   Person  Voice   Value 1 >20
4   6   2   Person  Voice   Value 2 P
5   2   3   Mail    OCR Value 1 A
6   7   3   Mail    OCR Value 2 I
7   3   4   Dictation   Understandable  Value 1 S
8   8   4   Dictation   Understandable  Value 2 I
9   4   5   Web Logic   Value 1 R
10  9   5   Web Logic   Value 2 S
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.