Changing Only One Row to Column in Python

Changing only one row to column in Python

Use unstack if MultiIndex one column DataFrame:

print (df.index)
MultiIndex(levels=[['A', 'B', 'C'], ['off', 'on', 'rmt_off']],
labels=[[0, 0, 1, 1, 1, 2, 2, 2], [1, 0, 1, 0, 2, 1, 0, 2]],
names=['computer', 'status'])

print (df['count'].unstack())
status off on rmt_off
computer
A 44.0 45.0 NaN
B 32.0 34.0 12.0
C 23.0 23.0 2.0

EDIT: Need replace empty strings to NaNs with forward filling, last use pivot:

df['computer'] = df['computer'].mask(df['computer'] == '').ffill()
df = df.pivot('computer','status', 'count')

How to switch column elements for only one specific row in pandas?

You're sooooo close! The error you're getting stems from trying to slice df.index([df.loc[df['columna'] == x]]). The parentheses are unneeded here and this should read as: df.index[df.loc[df['columna'] == x]].

However, here's an example on how to swap values between columns when provided a value (or multiple values) to swap at.

Sample Data

df = pd.DataFrame({
"A": list("abcdefg"),
"B": [1,2,3,4,5,6,7]
})

print(df)
A B
0 a 1
1 b 2
2 c 3
3 d 4
4 e 5
5 f 6
6 g 7

Let's say we're going to swap the values where A is either "c" or "f". To do this we need to first create a mask that just selects those rows. To accomplish this, we can use .isin. Then to perform our swap, we actually take the same exact approach you had! Including the .to_numpy() is very important, because without it Pandas will actually realign your columns for you and cause the values to not be swapped. Putting it all together:

swap_at = ["c", "f"]
swap_at_mask = df["A"].isin(swap_at) # mask where columns "A" is either equal to "c" or "f"

# Without the `.to_numpy()` at the end, pandas will realign the Dataframe
# and no values will be swapped
df.loc[swap_at_mask, ["A", "B"]] = df.loc[swap_at_mask, ["B", "A"]].to_numpy()

print(df)
A B
0 a 1
1 b 2
2 3 c
3 d 4
4 e 5
5 6 f
6 g 7

Convert some columns into row and one column's rows into columns in python

Pivot and stack

df.pivot('City', 'Sales').stack(0).rename_axis(['City', 'Year'])


Sales        X    Y    Z
City Year
A 2016 100 90 130
2017 120 120 160
2018 160 130 190
B 2016 200 290 230
2017 220 220 260
2018 260 230 290
C 2016 300 390 330
2017 320 320 360
2018 360 330 390

How to convert particular column values to one row based on other column in python?

You need to provide information on the columns you want to put the values in 'col2' into. I think this is what you want:

mapping = {101: 'pro1', 102: 'pro2', 103: 'pro3'}
df['cols'] = df.col2.map(mapping)
df.pivot(index='col1', values='col2', columns='cols')

Edit: You can create the mapping automatically like so:

df['cols'] = 'pro' + df.col2.astype(str)

Edi2: You can check if your data has duplicate rows like so:

df.duplicated()

If you simply want to get rid of these you can do

df.loc[~df.duplicated()].pivot(index='col1', values='col2', columns='cols')

How to replace only 1 element in a DataFrame (Python-Pandas)

You could do something like:

if df.iloc[row]['Diff_number'] < 0:
df.at[row, 'Diff_number'] = df.iloc[row]['Number']

How can I efficiently replicate a pandas row, changing only one column?

Pandas solution for 0.25+ version with Series.str.split and DataFrame.explode:

df = df.assign(v2 = df.v2.str.split(',')).explode('v2').reset_index(drop=True)
print (df)
v1 v2
0 a A1
1 b A2
2 b A3
3 c B4
4 d A5
5 d B6
6 d B7

For oldier versions and also perfromace should be better with numpy:

from itertools import chain

s = df.v2.str.split(',')
lens = s.str.len()
df = pd.DataFrame({
'v1' : df['v1'].values.repeat(lens),
'v2' : list(chain.from_iterable(s.values.tolist()))
})
print (df)
v1 v2
0 a A1
1 b A2
2 b A3
3 c B4
4 d A5
5 d B6
6 d B7

Pandas: Append copy of rows changing only values in multiple columns larger than max allowed to split bin values

Let's approach in the following steps:

Step 1: Preparation of split values:

Define custom lambda function to turn Data 1, Data 2 into lists of values split with Max. Allowed if larger than it. Hold the expanded lists in 2 new columns Data 1x, Data 2x:

f = lambda x, y, z: [z] * (x // z) + [x % z] + [0] * (max(x//z, y//z) - x//z)

df['Data 1x'] = df.apply(lambda x: f(x['Data 1'], x['Data 2'], x['Max. Allowed']) , axis=1)
df['Data 2x'] = df.apply(lambda x: f(x['Data 2'], x['Data 1'], x['Max. Allowed']) , axis=1)

The lambda function is designed to add 0 into the lists to make the number of elements in lists in the same row to have the same lengths.

Intermediate result:

print(df)

Index Data 1 Data 2 Max. Allowed Data 1x Data 2x
0 1 1 2 3 [1] [2]
1 2 10 5 8 [8, 2] [5, 0]
2 3 7 12 5 [5, 2, 0] [5, 5, 2]

Step 2: Explode split values into separate rows:

Case 1: If your Pandas version is 1.3 or above

We use DataFrame.explode() to explode the 2 new columns: (this part of feature to explode multiple columns requires Pandas version 1.3 or above)

df = df.explode(['Data 1x', 'Data 2x'])

Case 2: For Pandas version lower than 1.3, try the following way to explode:

df = df.apply(pd.Series.explode)

Case 3: If the above 2 ways to explode don't work in your programming environment, use:

df_exp = df.explode('Data 1x')[['Index', 'Data 1', 'Data 2', 'Max. Allowed']].reset_index(drop=True)
df_1x = df.explode('Data 1x')[['Data 1x']].reset_index(drop=True)
df_2x = df.explode('Data 2x')[['Data 2x']].reset_index(drop=True)

df = df_exp.join([df_1x, df_2x])

Result:

print(df)

Index Data 1 Data 2 Max. Allowed Data 1x Data 2x
0 1 1 2 3 1 2
1 2 10 5 8 8 5
1 2 10 5 8 2 0
2 3 7 12 5 5 5
2 3 7 12 5 2 5
2 3 7 12 5 0 2

Step 3: Formatting to the required output:

# select and rename columns
df = (df[['Index', 'Data 1x', 'Data 2x', 'Max. Allowed']]
.rename({'Data 1x': 'Data 1', 'Data 2x': 'Data 2'}, axis=1)
.reset_index(drop=True)
)

# reset the `Index` values
df['Index'] = df.index + 1

Final result:

print(df)


Index Data 1 Data 2 Max. Allowed
0 1 1 2 3
1 2 8 5 8
2 3 2 0 8
3 4 5 5 5
4 5 2 5 5
5 6 0 2 5

How to replace a row in pandas with multiple rows after applying a function?

You can use

df[0].str.split(r'\.(?!$)').explode().reset_index(drop=True).str.rstrip('.')

Output:

0               A sentence
1 Another sentence
2 More sentences here
3 Another line of text

The \.(?!$) regex matches a dot not at the end of the string. The .explode() splits the results across rows and the .reset_index(drop=True) resets the indices. .str.rstrip('.') will remove trailing dots.

You can also use Series.str.findall version:

>>> df[0].str.findall(r'[^.]+').explode().reset_index(drop=True)
0 A sentence
1 Another sentence
2 More sentences here
3 Another line of text

where [^.]+ matches any one or more chars other than . char.



Related Topics



Leave a reply



Submit