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 NaN
s 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
How to Convert Strings With Billion or Million Abbreviation into Integers in a List
Python Json.Loads Valueerror, Expecting Delimiter
How to Convert Number 1 to a Boolean in Python
Python Tkinter Return Value from Function Used in Command
Find the Index of a Value in a 2D Array
How to Convert a 1 Channel Image into a 3 Channel With Opencv2
Finding the Index of the First Occurrence of Any Item in a List
Identifying the Range of a Color in Hsv Using Opencv
How to Calculate Average a Dictionary from List of Dictionary Data
Use Variable as Key Name in Python Dictionary
How to Remove/Delete a Virtualenv
Most Pythonic Way to Kill a Thread After Some Period of Time
How to Overwrite the Previous Print to Stdout
How to Install Python Packages from the Tar.Gz File Without Using Pip Install
How to Make a Tkinter Label Background Transparent