You are first adding R0Cx and then R1Cxy. You need to add RxCy. So try:
newlist = []
row = A
col = B
for x in range (0, row):
newlist.append([])
for y in range(0, col):
newlist[x].append('R' + str(x) + 'C' + str(y))
print(newlist)
Answer from Sefe on Stack OverflowYou are first adding R0Cx and then R1Cxy. You need to add RxCy. So try:
newlist = []
row = A
col = B
for x in range (0, row):
newlist.append([])
for y in range(0, col):
newlist[x].append('R' + str(x) + 'C' + str(y))
print(newlist)
You have to fill columns in a row while still in that row:
rows = []
row = 2
col = 3
for x in range(0, row):
columns = []
for y in range(0, col):
columns.append('R' + str(x) + 'C' + str(y))
rows.append(columns)
print(rows)
will print:
[['R0C0', 'R0C1', 'R0C2'], ['R1C0', 'R1C1', 'R1C2']]
You need to add the columns one by one.
for col in new_cols:
df[col] = 0
Also see the answers in here for other methods.
Use assign by dictionary:
df = pd.DataFrame({
'A': ['a','a','a','a','b','b','b','c','d'],
'B': list(range(9))
})
print (df)
0 a 0
1 a 1
2 a 2
3 a 3
4 b 4
5 b 5
6 b 6
7 c 7
8 d 8
new_cols = ['new_1', 'new_2', 'new_3']
df = df.assign(**dict.fromkeys(new_cols, 0))
print (df)
A B new_1 new_2 new_3
0 a 0 0 0 0
1 a 1 0 0 0
2 a 2 0 0 0
3 a 3 0 0 0
4 b 4 0 0 0
5 b 5 0 0 0
6 b 6 0 0 0
7 c 7 0 0 0
8 d 8 0 0 0
Pandas >= 0.25
Pandas can do this in a single function call via df.explode.
df.explode('column_x')
column_a column_b column_x
0 a_1 b_1 c_1
0 a_1 b_1 c_2
1 a_2 b_2 d_1
1 a_2 b_2 d_2
Note that you can only explode a Series/DataFrame on one column.
Pandas < 0.25
Call np.repeat along the 0th axis for every column besides column_x.
df1 = pd.DataFrame(
df.drop('column_x', 1).values.repeat(df['column_x'].str.len(), axis=0),
columns=df.columns.difference(['column_x'])
)
df1['column_x'] = np.concatenate(df['column_x'].values)
df1
column_a column_b column_x
0 a_1 b_1 c_1
1 a_1 b_1 c_2
2 a_2 b_2 d_1
3 a_2 b_2 d_2
You can repeat index values:
lens = df['column_x'].str.len()
a = np.repeat(df.index.values, lens)
print (a)
[0 0 1 1]
df = df.loc[a].assign(column_x=np.concatenate(df['column_x'].values)).reset_index(drop=True)
print (df)
column_a column_b column_x
0 a_1 b_1 c_1
1 a_1 b_1 c_2
2 a_2 b_2 d_1
3 a_2 b_2 d_2
Starting from Pandas 0.25.0, there is internal method DataFrame.explode(), which was designed just for that:
res = df.explode("b")
output
In [98]: res
Out[98]:
a b
0 1 1
0 1 2
1 2 2
1 2 3
1 2 4
2 3 5
Solution for Pandas versions < 0.25: generic vectorized approach - will work also for multiple columns DFs:
assuming we have the following DF:
In [159]: df
Out[159]:
a b c
0 1 [1, 2] 5
1 2 [2, 3, 4] 6
2 3 [5] 7
Solution:
In [160]: lst_col = 'b'
In [161]: pd.DataFrame({
...: col:np.repeat(df[col].values, df[lst_col].str.len())
...: for col in df.columns.difference([lst_col])
...: }).assign(**{lst_col:np.concatenate(df[lst_col].values)})[df.columns.tolist()]
...:
Out[161]:
a b c
0 1 1 5
1 1 2 5
2 2 2 6
3 2 3 6
4 2 4 6
5 3 5 7
Setup:
df = pd.DataFrame({
"a" : [1,2,3],
"b" : [[1,2],[2,3,4],[5]],
"c" : [5,6,7]
})
Vectorized NumPy approach:
In [124]: pd.DataFrame({'a':np.repeat(df.a.values, df.b.str.len()),
'b':np.concatenate(df.b.values)})
Out[124]:
a b
0 1 1
1 1 2
2 2 2
3 2 3
4 2 4
5 3 5
OLD answer:
Try this:
In [89]: df.set_index('a', append=True).b.apply(pd.Series).stack().reset_index(level=[0, 2], drop=True).reset_index()
Out[89]:
a 0
0 1 1.0
1 1 2.0
2 2 2.0
3 2 3.0
4 2 4.0
5 3 5.0
Or bit nicer solution provided by @Boud:
In [110]: df.set_index('a').b.apply(pd.Series).stack().reset_index(level=-1, drop=True).astype(int).reset_index()
Out[110]:
a 0
0 1 1
1 1 2
2 2 2
3 2 3
4 2 4
5 3 5
Here is another approach with itertuples -
df = pd.DataFrame({"a" : [1,2,3], "b" : [[1,2],[2,3,4],[5]]})
data = []
for i in df.itertuples():
lst = i[2]
for col2 in lst:
data.append([i[1], col2])
df_output = pd.DataFrame(data =data, columns=df.columns)
df_output
Output is -
a b
0 1 1
1 1 2
2 2 2
3 2 3
4 2 4
5 3 5
Edit: You can also compress the loops into a single code and populate data as -
data = [[i[1], col2] for i in df.itertuples() for col2 in i[2]]
You're over complicating this simple problem:
import csv
with open('test.txt') as f, open('out.csv','w') as f2:
writer = csv.writer(f2, delimiter = '\n')
for line in f:
x, y = line.split()
writer.writerow([y]*int(x))
output:
>>> cat out.csv
3
7
7
7
7
8
8
This should do it
with open('path/to/input') as infile, open('path/to/output', 'w') as outfile:
for line in infile:
mult, val = line.strip().split()
outfile.write('\n'.join([val for _ in xrange(int(mult))]))
outfile.write('\n')

